Fail hard with raml-js-parser: unable to resolve 'fs'


#1

Okay, completely new to RAML and it’s tooling here, so be gentle. Working my way toward using the api-notebook which looks exceptionally cool. I wanted to try the RAML JavaScript parser (raml-js-parser) with some RAML I crufted up, but I am failing hard, and I don’t understand why, and it has nothing to do with my RAML because I’m not even getting that far.

I built/packaged the RAML JS parser and wrote a little node app using it to parse the RAML:

var RamlParser = require('./raml-parser').RamlParser;
var parser = new RamlParser();
parser.loadFile('./items/items.raml').then(
    function(result) {
        console.log(result);
    },
    function(err) {
        console.log('err: '+JSON.stringify(err));
    });

This little app fails with the following error:

{"context":"while fetching ./items/items.raml","context_mark":null,"message":"cannot fetch ./items/items.raml (TypeError: undefined is not a function)","problem_mark":null}

I’ve debugged through the RAML JS parser code and found it is failing on the first line below, (about line 2399):

    _dereq_('fs').readFile(file, function(err, data) {        
       if (err) {
          return deferred.reject(new exports.FileError("while reading " + file, null, "cannot read " + file + " (" + err + ")", _this.start_mark));
       } else {
         return deferred.resolve(data.toString());
       }

The error is saying that ‘readFile’ cannot be resolved on the result of dereq(‘fs’), which I assume is just trying to resolve node’s fs. The result of that resolution is just an naked object, btw, not the fs code. Now, I’ve never had a problem using the fs lib from node before anywhere. I’m on a Mac if that’s relevant.

I tried updating to node 0.12. No joy.

I really, really want to like RAML. I think it is superior to other alternatives in every way, except the tooling. Compared to what it took to get a working, code and doc generating environment up with Swagger, for instance, this experience has been abysmal. Please help restore (establish?) my confidence in RAML, et. al. Thanks.


#2

Hi @lorenjerickson,

thanks for you feedback. I am not really sure if I can help you a lot, but if you have a look here https://github.com/sichvoge/raml-generator/blob/master/bin/index.js#L35 you see that other tools are using it as well and it is working. I’ll definitely try that later to see if there is any mistake. Did you follow the instructions inside the https://github.com/raml-org/raml-js-parser repo?

With regards to your last section: Could you please elaborate a little bit more about what you’re missing, what you think is abysmal, and what you think is better in Swagger? We are listening and try to be better in those things, but we also need people giving their opinion :wink:

Please see this topic to express your feelings: http://forums.raml.org/t/raml-experience-help-for-tutorial-improvements/737/3

:smiley:

Thanks,
Christian


#3

Hi Christian,
Don’t get me wrong. I think RAML and it’s associated tools have a lot of promise, and are clearly superior (on paper) to other offerings, but they are far from bulletproof or turnkey in my opinion. My “abysmal” experience stems from the fact that nothing I have tried to accomplish with these tools worked out of the box, on the first try. Just so we’re clear on what I have tried:

  • parsing RAML with the JS parser (hence this post)
  • executing RAML-defined services using the JS client downloaded from the API console
  • designing RAML interface in API designer with heavy use of includes
  • running API notebook with the intent of exercising the API defined above

To date, none of these exercises have come without more than their fair share of pain. The JS code parser use case should have been very simple. I didn’t give it more than a trivial RAML example to work with and it failed for the above reason, which makes absolutely no sense. And I still have not determined the cause.

The second use case, the downloaded API just doesn’t work. It either hangs completely or errors out after a significant delay. I can see the request hit the server but it never completes successfully. If I manually compose the URL for the same request it works just fine every time. Could be in my RAML definition but there’s no way to know for sure. I’ll have to debug Popsicle to figure out what’s going on.

The third use case is frustrating due to inadequate error reporting and destructive quirks in the editor. Many, many times I’d get a red outline box on the editor window but no indication of where the error is. When the error marker does show up it is misplaced and references something buried in an include. I would prefer to see those errors on the included file, but of course there is no error reported there. The API designer also constantly lost changes I had made or overwrote the contents of one file with another when rapidly switching between files, which is pretty much required because of the issue above. I finally had to abandon the API designer altogether in favor of a text editor with RAML/YAML syntax support. (Also, if you’re going to store the files in localStorage, at least give me a download/export option.)

The fourth use case fails because of the github provider was missing (or some similar error). I think the integration with github is cool, but don’t want to have to figure that out just to poke around in an API I have defined locally. Admittedly, I did not spend a lot of time trying to make this work, and am not inclined to do so until the more serious concerns above are addressed.

In contrast, everything I asked Swagger to do, it did correctly and without hesitation or intervention of any kind. I tested it extensively to the extent that this tool supports some of the things that RAML+tooling is supposed to do. Swagger may not have as rich a feature set as RAML+tooling, but it works every time. I am sorry to say that RAML, et. al., does not, at least for me.

I am an experienced NodeJS, JavaScript, AngularJS and REST developer and I’m not opposed to applying some elbow grease to work through these issues. It’s just more effort than I had hoped for. After all, my purpose here is to publish an API, not maintain the tools required to do so.

For the record, I have already recommended RAML+tooling over Swagger for a project my company is pursuing and I am dearly hoping that wasn’t a mistake. The fact that the JS client downloadable from the API console does not work (at all) is a real deal breaker though.

Regards


#4

@lorenjerickson What file are you trying to run in node? The dist/ directory is only for browsers (it looks like you’re trying to run that on node?). Try requiring it directly or using the file listed in the package.json under "main" (lib/raml.js). Does that work for you? Please feel free to message me directly and we can figure things out :smile:


#5

Hi @lorenjerickson,

thanks a lot for your response and feedback. I’ll try to tackle some of your concerns bit by bit in different posts to different times as i have to see what was the problem, and how I can help you.

Let’s step back to the initial problem you had with the js parser. I think the code you provided is not correct. I tried it as well and it was not working. But following the example on the github page https://github.com/raml-org/raml-js-parser#load worked perfectly fine. I did the following:

  1. initialize NodeJS project (npm init) and add the raml-parser as dependency
  2. added the example code to a new js file
  3. execute and the RAML content will be print out to the console

Can you please try it again and follow the examples on the github repo. Please let me know if that works.


#6

Okay, I was finally able to get a very simple RAML file parsed with the JS parser. I pared back the sample RAML I was using even further.

#%RAML 0.8
title: Sample API
baseUri: https://{host}.sample.com/{version}
version: v1
baseUriParameters:
    host:
        type: string
        enum: [ dev, test, prod ]
/items:
  get:
    description: Return all items in the project
    responses:
      200:
        body:
          application/json:
  /{id}:
    get:
      description: Return a single item for the given identifier.
      responses:
        200:
          body:
            application/json:

I copy/pasted the first example from raml-js-parser and tweaked the filename:

  var raml = require('raml-parser');
  raml.loadFile('test.raml').then(
    function(result) {
        console.log(result);
    },
    function(err) {
        console.log('err: '+JSON.stringify(err));
    });

And got the expected output:

{ title: 'Sample API',
  baseUri: 'https://{host}.sample.com/{version}',
  version: 'v1',
  baseUriParameters:
   { host:
      { type: 'string',
        enum: [Object],
        displayName: 'host',
        required: true },
     version:
      { type: 'string',
        required: true,
        displayName: 'version',
        enum: [Object] } },
  protocols: [ 'HTTPS' ],
  resources:
   [ { relativeUri: '/items',
       methods: [Object],
       resources: [Object],
       relativeUriPathSegments: [Object] } ] }

I will try this again tomorrow with a more realistic RAML example. But I am glad to see this work. Blake was probably right about me misusing the browser version of the parser, although I cannot recall how I got there from here. So yes, some of my pain has been self-inflicted. I appreciate your patience.

Regards


#7

Making progress on these issues. Was able to generate a JS implementation of a very complex RAML with the command line tool (client-generator) and execute a request with that JS code. The code available via the “download JS” link embedded in the console still does not work for me though. Progress.

Regards.


#8

Happy to hear that. Blake told me he will have a look on that particular problem. If you need anything else in the meanwhile - please let me know.