Giter VIP home page Giter VIP logo

swagger-node-runner's People

Contributors

behrangsa avatar camsjams avatar ghermeto avatar hanspagh avatar irond13 avatar maugenst avatar osher avatar penx avatar shole avatar theganyo avatar whitlockjc avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

swagger-node-runner's Issues

Response validation error is not passing response validation. Broken / truncated validation response body

When I have a response validation error, I'm left with a broken response message, because it seems the response message itself does not pass the validation, or it could be something else entirely, I just can't pinpoint the issue. I'm not entirely sure how things break in this way, perhaps it's got something to do with Content-Length, or something else.

I'm posting this issue to offer a work-around to others, and perhaps get some feedback on this issue.

So I worked around this problem by creating my own json_error_handler fitting, and instead of sending the full error in the response, I simply just return the error message, and console.error the err.results.

The problem is here: https://github.com/theganyo/swagger-node-runner/blob/424734a6000da517f6336d9f8ce006c5cfbd7b83/fittings/json_error_handler.js#L36

My code change: [edit] Don't do this, see below

next(null, JSON.stringify({
  message: err.message
}));

This was causing me some pain, I hope this helps others.

refine the dist. package with .npmignore file

I just found that the resulting distribution package sent to npm contains the tests...

I don't know how to create a PR for adding a file, but there you go...

.npmignore

test
.gitignore
.jshintrc
.npmignore
.travis.yml

New changes are not present

changes in #16 doesn't seem to be present even after I delete my node_module folder, am I doing something completely wrong?

204 No Content

There's a codepath I'm not comfortable with, I need your take on this.

from W3 spec:

The 204 response MUST NOT include a message-body, and thus is always terminated by the first empty line after the header fields.

So, in contrast, IMHO - the case slips our code here:
https://github.com/theganyo/swagger-node-runner/blob/master/lib/connect_middleware.js#L87

the problem is that if ctx.output is falsful - including zero (0), empty string (""), null, undefined, and obviously false - the respondse.end() is not called, where the last in chain-of-responsibility is usually the framework, wich ends with it's default response, usually 404 in the form of cannot GET /the-path.

All of the above (except undefined maybe) are legit replies the server may be required to provide, regardless to 204 status code, where there should be cases where the server should emit no body.

Am doing something wrong or missing anything?

If I'm not missing anything - LMK, and I'll start a PR to fix this...

Response validation missing?

It appears that swagger_validate fitting no longer supports response validation. What's the long term plan? Is there a recommended work around for now?

There appears be code in the swagger-tools project's swagger-validator middleware, but it's not clear how these two should be integrated (and swagger-tools is technically deprecated).

cors: name collision

I'm trying to create some reusable pipe fittings packed as simple npm packages.

So to prove the concept I placed a simple node_modules/required-fitting/index.js (together with a standard package.json) in same folder, as follows:

var debug = require('debug')('fitting:required-fitting');
module.exports = function create(fittingDef) {
    console.log('required-fitting', fittingDef);
    return function stam(ctx, cb) {
        console.log('REQUIRED-FITTING IS CALLED');
        cb()
    }
}

And added to the config:

So:

swagger:
  fittingsDirs:             [ lib/fittings, node_modules ]
  ...

Alas - the pipe explodes. The error is observed on the response as {"message":"undefined is not a function"}, with NO MENTION of it on the server log

It appears to explode on cors, which is now ambiguous between the two paths:

  • node_modules/cors
  • lib/fitting/cors.js

playing with order of paths in fittingsDir did not help :(

I can PR to rename lib/fitting/cors.js to lib/fitting/swagger_cors.js or anytihng of that sort, however, it looks like a breaking change.

I think the situation points also to an additional problem:
I think the fitting builder that calls the fitting factory may be required to make sure that the factory returns a function in the correct arity. (the vanilla cors package is a f(1) factory that returns f(3))

I did not miss the part about type:node-machine that requires some overhead plus pushes me to experimental zone, which I would totally prefer to avoid at this stage... my client wont approve of anything with experimental labelled on it...

Thoughts?

Endpoints with parameters in body requested without content-type crashes app

On https://github.com/theganyo/swagger-node-runner/blob/master/fittings/swagger_params_parser.js#L40, it says 'we do not check for errors here' Why is that?

There's a lot of nice validation in https://github.com/apigee-127/sway/blob/master/lib/types/parameter.js#L118 that results in exceptions. Since they are not caught in the parser, they will typically take down the process.

Say you have a swagger spec with an endpoint with a parameter "in: formData". Everything is working fine and dandy. However, if a (malicious?) client requests the endpoint and omits the Content-Type header, then that causes req.body to be undefined and an exception in to be thrown (https://github.com/apigee-127/sway/blob/master/lib/types/parameter.js#L147). Since that is not caught, gone is your service.

compeating efforts to JSON.stringify ctx.output

Edited: beautify and used more precise language

Hi.
I noted compeating efforts between:
json_error_handler.js#L42
json_error_handler.js#L60
and
connect_middleware.js#L127

If the concern of serializing a model object to a string is a concern of the connect_middleware, then the json_error_handler should not stringify, but leave a model object (the Error, perhaps augmented with statusCode or so)

I came to this thought when I approached a requirement to format error responses with in a custom envelope that is accustomed in the corp I do the job for.

My initial thought was :

swagger-route-error:
 - name: json_error_handler
 - fitting/the-corp-envelope

swagger-router:
 - onError: swagger-route-error
 - ...

Then I noted that the error handler leaves a string. If I want to manipulate it - I'll have to parse it, where it was an object just one step before...

.

I began to believe that the safe serialization logic belongs to connect_middleware, and should be agnostic to wether it's an error or not

(I mean, serialization error will still raise statusCode to 500, but it's not unique to json_error_handler)

What do you think?

Route parameters aren't available in Hapi

I'm using swagger-node-runner through swagger-hapi. The related dependencies are:

├─┬ [email protected]
│ └─┬ [email protected]
│ └─┬ [email protected]
│ └── [email protected]

When handling a request with a parameter in the path, the request.swagger.params object is undefined. I looked around request and request.swagger thinking it could've been renamed, but couldn't find the parameter anywhere.

Downgrading swagger-hapi to 0.1.0, which in turn downgrades swagger-node-runner to 0.5.13 fixes the issue.

If it helps, the handler I'm running is at https://github.com/opentrials/api/blob/master/api/controllers/trials.js#L4.

Fitting specific to a route/path?

Hi,
Just wondering if there's a way to specify a fitting (or middleware) to be executed for a specific path or even an operation for a specific path without writing an extension as seen in Volos[1]? Much like as you'd specify a middleware for a connect/express route.

For the time being the only option I can think of is a generic fitting that execute as part of swagger_controllers, but the downside of that is I need to check for the path I'm interested and invoke the middleware on a match. Not very elegant sadly.

[1] https://github.com/apigee-127/volos/tree/master/swagger

multiple swagger definition file?

Is there a way to load multiple swagger definition files?

This is needed for handling API versioning as swagger defines one API version per definition file.

Thanks.

OPTIONS requests from the browser / CORS are not working, getting 405

This block of code is preventing OPTIONS calls in the cors module from working. The cors fitting middleware is never hit because a 405 is returned in the connect middleware.

      if (!operation) {
        var path = runner.getPath(req);
        if (!path) { return next(); }

        if (!path['x-swagger-pipe']) {
          var msg = util.format('Path [%s] defined in Swagger, but %s operation is not.', path.path, req.method);
          var err = new Error(msg);
          err.statusCode = 405;

          var allowedMethods = _.map(path.operationObjects, function(operation) {
            return operation.method.toUpperCase();
          });
          err.allowedMethods = allowedMethods;

          res.setHeader('Allow', allowedMethods.sort().join(', '));
          return next(err);
        }
      }

Handle basePath together with express sub-app

I have this URL format: domain.com/api/resource
The baseUrl defined in swagger.yaml is /api
The express configured so that the /api is just a sub-app:

app = express();
apiApp = express();
app.use('/api', apiApp);

The swagger middleware is then added into apiApp.

Both swagger definition and express already configured to use the /api basePath, but connect middleware bypass it by calling next() because the runner.getPath return undefined.

Note the api.getPath, the pathOrReq.url here is returning only the sub path. In this case the pathOrReq.url = '/resource' instead of '/api/resource'. Therefore the regexp and isArray return false.

I suggest we fix this by calling api.getPath(req.originalUrl) either in runner or connect middleware since originalUrl contain the full path.

Refer to this also apigee-127/sway#81

Restify middleware: swagger path params are not processed

Paths are directly passed to the app object in lib/restify_middleware.js which results to not having path params parsed. Restify uses :param syntax for specifying path parameters and Swagger uses {param} syntax. This results 404s when trying to access an url with dynamic part in it.

 api.pathObjects.forEach(function(path) {
      if (path.operationObjects && path.operationObjects.length > 0) {
        path.operationObjects.forEach(function(operation) {
          registerHandler(path.path, operation.method);
        });
      } else {
        ALL_METHODS.forEach(function(method) {
          registerHandler(path.path, method);
        });
      }
    });

Existing security handler broken after upgrade to Sway 1.0 based release

Hi,
Firstly congrats on the Sway 1.0 based release. Much appreciated. It seems that after the release, my existing security handlers are no longer working.

Pre-upgrade npm ls shows I had been using:
[email protected]
[email protected]
[email protected]

I should mention that I was using API level security instead of specifying security per route, i.e. in my swagger.yaml file I had:

# API security. Applies to all routes
security:
  - BasicAuth: []
# Routes
paths:
  /stars/{starId}/accounts:
    x-swagger-router-controller: star-controller
    get:
      description: Returns accounts for a star identified by it's id
...
# API security definition
securityDefinitions:
  BasicAuth:
    type: basic

Post upgrade, I'm using:
[email protected]
[email protected]
[email protected]

Looking at the security fitting[1] it seems that operation comes back as undefined and this suggests that support for API level security has somehow been broken.

I've currently worked around by specifying operation level security for each route and that's fine, but I wanted to highlight this nevertheless as API level security is part of the spec and should be supported.

[1] https://github.com/theganyo/swagger-node-runner/blob/master/fittings/swagger_security.js#L32

500 error instead of 405 on non allowed method

When request to non allowed method in swagger.yaml I get a 500 instead of 405:

error: Sending 500 ("Server Error") response: 
 Error: Path [aPathApi] defined in Swagger, but GET operation is not.
    at middleware (/projectdir/node_modules/swagger-sails-hook/node_modules/swagger-node-runner/lib/connect_middleware.js:31:21)
...
at callbacks  (/projectdir/node_modules/sails/node_modules/express/lib/router/index.js:167:11) { [Error: Path [aPathApi] defined in Swagger, but GET operation is not.] statusCode: 405, allowedMethods: [ 'DELETE', 'POST' ] }

Is there an option to overide this ?

https://github.com/theganyo/swagger-node-runner/blob/master/lib/connect_middleware.js#L40

Thanks

Latest NPM breaks swagger-node-runner CORS

All modules are in a flat format now and it appears that having swagger-node-runner/fittings/cors.js and the module cors (in the new flat format) breaks what is loaded via require.

I can test this theory by installing a sample project with the latest npm (3.3.12) and seeing it break then going into the swagger-node-runner module and renaming the cors wrapper (and relevant config for bagpipes) and it works.

Not sure of an elegant workaround for this. Renaming fittings/cors.js would cause problems with existing projects.

Not possible to configure CORS origin using a regexp

https://github.com/expressjs/cors#configuration-options shows that you can set origin to a regexp to only allow CORS request from a given domain:

RegExp - set origin to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern /example.com$/ will reflect any request that is coming from an origin ending with "example.com".

Is there a way to pass such a regexp in the config ? If not, how may I create my own cors middleware and use it in the swagger-node-runner setup ?

500 error during multipart/form-data send unexpected file param name (with sails)

If I try to upload unexpected file name param I get a 500 error, I expected a 400 Bad Request instead
Perhaps I am missing something ?

Example:

$ curl -F "badfilename=@s" --header 'Content-Type: multipart/form-data' 'http://localhost:1337/hello' -v
*   Trying ::1...
* Connected to localhost (::1) port 1337 (#0)
> POST /hello HTTP/1.1
> Host: localhost:1337
> User-Agent: curl/7.43.0
> Accept: */*
> Content-Length: 240
> Expect: 100-continue
> Content-Type: multipart/form-data; boundary=------------------------7a61cdece2908f90
>
< HTTP/1.1 100 Continue
< HTTP/1.1 500 Internal Server Error
< Access-Control-Allow-Origin: *
< Access-Control-Allow-Credentials:
< Access-Control-Allow-Methods:
< Access-Control-Allow-Headers:
< Access-Control-Expose-Headers:
< X-Content-Type-Options: nosniff
< Content-Type: text/html; charset=utf-8
< Content-Length: 1476
< Date: Thu, 09 Jun 2016 05:44:22 GMT
< Connection: keep-alive
* HTTP error before end of send, stop sending
<
Error: Unexpected field<br> &nbsp; &nbsp;at makeError (/Users/cgaliber/dev/bugs/upload-swagger-sails/node_modules/multer/lib/make-error.js:12:13)<br> &nbsp; &nbsp;at wrappedFileFilter (/Users/cgaliber/dev/bugs/upload-swagger-sails/node_modules/multer/index.js:39:19)<br> &nbsp; &nbsp;at Busboy.&lt;anonymous&gt; (/Users/cgaliber/dev/bugs/upload-swagger-sails/node_modules/multer/lib/make-middleware.js:112:7)<br> &nbsp; &nbsp;at emitMany (events.js:127:13)<br> &nbsp; &nbsp;at Busboy.emit (events.js:201:7)<br> &nbsp; &nbsp;at Busboy.emit (/Users/cgaliber/dev/bugs/upload-swagger-sails/node_modules/busboy/lib/main.js:31:35)<br> &nbsp; &nbsp;at PartStream.&lt;anonymous&gt; (/Users/cgaliber/dev/bugs/upload-swagger-sails/node_modules/busboy/lib/types/multipart.js:213:13)<br> &nbsp; &nbsp;at emitOne (events.js:96:13)<br> &nbsp; &nbsp;at PartStream.emit (events.js:188:7)<br> &nbsp; &nbsp;at HeaderParser.&lt;anonymous&gt; (/Users/cgaliber/dev/bugs/upload-swagger-sails/node_modules/dicer/lib/Dicer.js:51:16)<br> &nbsp; &nbsp;at emitOne (events.js:96:13)<br> &nbsp; &nbsp;at HeaderParser.emit (events.js:188:7)<br> &nbsp; &nbsp;at HeaderParser._finish (/Users/cgaliber/dev/bugs/upload-swagger-sails/node_modules/dicer/lib/HeaderParser.js:68:8)<br> &nbsp; &nbsp;at SBMH.&lt;anonymous&gt; (/Users/cgaliber/dev/bugs/upload-swagger-sails/node_modules/dicer/lib/HeaderParser.js:40:12)<br> &nbsp; &nbsp;at emitMany (events.js:127:13)<br> &nbsp; &nbsp;at SBMH.emit (events.js:201:7)
* Closing connection 0

Here is the error from node console

      Error: Unexpected field
      at makeError (node_modules/multer/lib/make-error.js:12:13)
      at wrappedFileFilter (node_modules/multer/index.js:39:19)
      at Busboy.<anonymous> (node_modules/multer/lib/make-middleware.js:112:7)
      at emitMany (events.js:127:13)
      at Busboy.emit (events.js:201:7)
      at Busboy.emit (node_modules/busboy/lib/main.js:31:35)
      at PartStream.<anonymous> (node_modules/busboy/lib/types/multipart.js:213:13)
      at emitOne (events.js:96:13)
      at PartStream.emit (events.js:188:7)
      at HeaderParser.<anonymous> (node_modules/dicer/lib/Dicer.js:51:16)
      at emitOne (events.js:96:13)
      at HeaderParser.emit (events.js:188:7)
      at HeaderParser._finish (node_modules/dicer/lib/HeaderParser.js:68:8)
      at SBMH.<anonymous> (node_modules/dicer/lib/HeaderParser.js:40:12)
      at emitMany (events.js:127:13)
      at SBMH.emit (events.js:201:7)

Here is an extract of swagger.yaml parameters section

      parameters:
        - name: stdout
          in: formData
          description: the file to upload
          required: false
          type: "file"

Path param of type array[integer] always fails on length 1

Swagger YAML Def:

/Permission:
    x-swagger-router-controller: permission
    get:
      tags: ['Permissions']
      description: Get either all permissions or a permission with a specific id
      operationId: getPermissions
      parameters:
        - $ref: "#/parameters/NodeIDs"
      responses:
        "200":
          description: Success
          schema:
            type: array
            items:
              $ref: "#/definitions/Permission"
        default:
          description: Error
          schema:
            $ref: "#/definitions/ErrorResponse"
 
parameters:
   NodeIDs:
    name: ids
    in: query
    description: A list of node ids (integers).
    type: array
    items:
      type: integer

Example command: curl -k https://0.0.0.0:3000/Permission?ids=123

Error:

{"message":"Validation errors","errors":[{"code":"INVALID_REQUEST_PARAMETER","errors":[{"code":"INVALID_TYPE","params":["array","integer"],"message":"Expected type array but found type integer","path":[],"description":"A list of node ids (integers)."}],"in":"query","message":"Invalid parameter (ids): Value failed JSON Schema validation","name":"ids","path":["paths","/Permission","get","parameters","1"]}]}

However the following works: curl -k https://0.0.0.0:3000/Permission?ids=1231,1231

The following behavior does not hold true when the yaml def changes to the following:

parameters:
   NodeIDs:
    name: ids
    in: query
    description: A list of node ids (integers).
    type: array
    items:
      type: string

However, I receive an error when I try to put an integer 1231 into a string.

I'd really love for a resolution to this.

Best,
Dan

Config module prolem

I tried to use swagger-node (with express) with the config module. I was loading all the config first and then used SwaggerExpress.create. This module was throwing "Cannot assign to read only property 'swagger' of [object Object]", stack trace:

TypeError: Cannot assign to read only property 'swagger' of [object Object]
at new Runner ([cut]\node_modules\swagger-node-runner\index.js:154:18)
at Object.module.exports.create ([cut]\node_modules\swagger-node-runner\index.js:54:3)
at Object.module.exports.create ([cut]\node_modules\swagger-express-mw\lib\index.js:30:10)
at Object. ([cut]\app.js:12:16)
at Module._compile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Function.Module.runMain (module.js:447:10)
at startup (node.js:141:18)
at node.js:933:3

I debugged the problem and used a (kinda) dirty hack - I load SwaggerExpress (and hence swagger-node-runner) before anything else, and suddenly it works. Anyway, it was not an expected behavior

I researched it deeper, and understood that this is related to the config object becoming immutable

So you should either update the docs with a note that this module should be loaded prior to config module reads (it writes to swagger variable), or alter the inner structure somehow.

Koa runner

Just started out in Koa and would be awesome to have this aswell.

Array parameters with default values

There seems to be an issue with default parameters when used in combination with arrays. I've added the following to the test-case swagger:

  /hello_w_default_array:
    x-swagger-router-controller: hello_world
    get:
      description: Returns 'Hello' to the caller
      operationId: hello_array
      parameters:
        - name: names
          in: query
          description: The names of the people to whom to say hello
          default: ["Tom", "Maria"]
          type: array
          items:
            type: string
          collectionFormat: csv

The test code in /tests/lib/common.js:

    it('should execute with default names', function(done) {
      request(this.app)
        .get('/hello_w_default_array')
        .set('Accept', 'application/json')
        .expect(200)
        .expect('Content-Type', /json/)
        .end(function(err, res) {
          should.not.exist(err);
          res.body.should.eql('Hello, Tom and Maria');
          done();
        });
    });

and the added function to the hello_world.js is:

...
  hello_array: hello_array,
...

function hello_array(req, res) {
  var hello = 'Hello';
  console.log(req.swagger)
  var names = req.swagger.params.names.value
  for (let n =0; n < names.length; n ++) {
    if (names.hasOwnProperty(n)) {
      if ((n + 1) === names.length){
        hello += " and "
      }else {
        hello += ", "
      }
      hello += names[n]
    }
  }
  res.json(hello);
}

And mocha test/lib/connect_middleware.js -g "with default names" fails with:

  1) connect_middleware standard controllers should execute with default names:
     Uncaught AssertionError: expected Error { message: 'expected 200 "OK", got 400 "Bad Request"' } to not exist
      at Test.<anonymous> (test/lib/common.js:72:22)
      at Test.assert (node_modules/supertest/lib/test.js:156:6)
      at Server.assert (node_modules/supertest/lib/test.js:127:12)
      at emitCloseNT (net.js:1521:8)

If I add a required: false the hello_array is properly identified but the names property is empty as if the default parameters are ignored. This could possibly be a upstream bug in sway as there seems to be an issue with how default arrays are passed. I think the package should have tests for default values so I've added them (see pull request) and therefore started reporting the issue here.

response validator attempt to validate non swagger operations

I've a error handler set up

swaggerExpress.runner.on('responseValidationError', function(validationResponse, request, response) { ... }

and I'm also serving up the swagger-ui using static serve.

However the hookResponseForValidation fails with

TypeError: Cannot read property 'validateResponse' of undefined api_1 | at ServerResponse.hookEnd (/app/node_modules/swagger-node-runner/lib/connect_middleware.js:163:63)

as operation is undefined on context.request.swagger.operation.validateResponse

I'll submit a pull request shortly but the gist of the change is to filter out based on

if(context.request.swagger.operation == undefined){ debug('not a swagger operation, will not validate response'); }

Restify middleware: basePath is not parsed

In lib/restify_middleware.js paths are attached directly to the app object without having the basePath in mind. This results to 404's.

 api.pathObjects.forEach(function(path) {
      if (path.operationObjects && path.operationObjects.length > 0) {
        path.operationObjects.forEach(function(operation) {
          registerHandler(path.path, operation.method);
        });
      } else {
        ALL_METHODS.forEach(function(method) {
          registerHandler(path.path, method);
        });
      }
    });

Various error handling issues

Hi there, I'm having a hard time with error handling. When a validation error is raised it comes back as an ugly JSON response with my request buffer attached. How do developers opt out, or modify this error object?

I am using a project generated with swagger project create, with express.

The other thing, is that the swagger error responses are coming back clipped. Example:

{"message":"Response validation failed: failed schema validation","code":"SCHE

This may be related to #30

Am I please able to have some help in resolving these issues?

Many thanks,
Wilfred

Global config replacement (x-a127-config style)

Scott,

As I am going through migrating from the a127 to the swagger-node new framework, I ran into the issue of trying to use the global replacement capability using the x-a127-config section in the yaml file.

We rely on this capability to be able to set different options per environment specifically for the volos libraries.

It seems that this was left out by design, assuming the app could provide the swagger instance via the config object. This is fine, but it would require the app to do something like the doConfigReplacements function in the a127-magic module.

Is there any way that a global yaml config section can be added to provide this kind of functionality or do you know of any other way that this can be achieved?

Thanks in advance for the help.

JC

No error thrown on unconfigured parameters

project
└─┬ [email protected]
  └── [email protected]

Issue: Passing an unconfigured parameter (not in swagger request schema) in a POST body doesn't throw a validation error.

Detail: Talking to the Swagger spec guys on IRC, it turns out that this "missing" behaviour isn't explicitly stated in the spec but was intended to exist, at least optionally. Does swagger-node-runner have this ability?

Adding a middleware after metadate middleware

Hi,
I have some middleware which check permission for specific API.
The validation is against path in a rules manifest like user/create.
until now i use it from express like this:

app.post("/user", permissionMW("users/create"), myControllerFunc);

Now i want to move this manifest path to be in the swagger yaml with x-permission-path.
but to use it i need to add this middleware to run after the metadate middleware (before/after the security middleware). so i will have access to the swagger object.
I want to somehow pass an hook MW which i can define from outside when to run it, and provide the func.
something like add to the config in the constructor:

MWhooks : {
"before[MWname]" : [myMW1, myMW2],
"after[MWname]" :  [myMW3, myMW4]
}

an actual value for this example will be :

myMW1 = function(req, res, next){
 if something next();
 throw err;
}
MWhooks  =  {
 "aftersecurity" :  [myMW1]
}

var config  = {
 MWhooks  : MWhooks 
}

Runner.create(config, function(err, runner) {
    if (err) { return cb(err); }
    cb(undefined, runner.expressMiddleware());
  });

What do you think about this? is this sound like a good solution?

request not making it to pipes error handler (caught in express router)

When deliberately making invalid requests (POST to PUT only endpoint) I receive a full error stack dump on the client side, looking at the debug log, the flow never makes it to pipeworks (and the tidy json_error_handler).

My project is based off the express swagger-node skeleton but I'm trying to upgrade to swagger-express-mw 0.7.0.

Valid requests the express router seems to be passed through and pipes handles everything correctly.

DEBUG=* log on invalid request:

 express:router dispatching POST /postOnly +2s
 express:router query  : /postOnly +0ms
 express:router expressInit  : /postOnly +1ms
 express:router middleware  : /postOnly +0ms
 finalhandler default 405 +1ms
 Error: Path [/postOnly] defined in Swagger, but POST operation is not.
    at middleware 
    at Layer.handle [as handle_request] 
    at trim_prefix 
    at /lib/router/index.js:280:7
    at Function.process_params 
    at next 
    at expressInit 
    at Layer.handle [as handle_request] 
    at trim_prefix 
    at 
    at Function.process_params 
    at next 
    at query 
    at Layer.handle [as handle_request] 
    at trim_prefix 
    at 
    at Function.process_params 
    at next 
    at Function.handle 
    at EventEmitter.handle 
    at Server.app 
    at emitTwo (events.js:106:13)
    at Server.emit (events.js:191:7)
    at HTTPParser.parserOnIncoming [as onIncoming] (_http_server.js:546:12)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:99:23)

My software versions:
"dependencies": {
"express": "^4.12.3",
"swagger-express-mw": "^0.7.0"
}

config file:

# swagger configuration file

# values in the swagger hash are system configuration for swagger-node
swagger:

  fittingsDirs: [ api/fittings ]
  defaultPipe: null
  swaggerControllerPipe: swagger_controllers  # defines the standard processing pipe for controllers

  # values defined in the bagpipes key are the bagpipes pipes and fittings definitions
  # (see https://github.com/apigee-127/bagpipes)
  bagpipes:

    _router:
      name: swagger_router
      mockMode: true
      mockControllersDirs: [ api/mocks ]
      controllersDirs: [ api/controllers ]

    _swagger_validate:
      name: swagger_validator
      validateResponse: false

    _json_error_handler:                       # <= Add this definition
      name: json_error_handler
      handle500Errors: true

    # pipe for all swagger-node controllers
    swagger_controllers:
      - onError: _json_error_handler
      - cors
      - swagger_params_parser
      - swagger_security
      - _swagger_validate
      - express_compatibility
      - _router

    # pipe to serve swagger (endpoint is in swagger.yaml)
    swagger_raw:
      name: swagger_raw

# any other values in this file are just loaded into the config for application access...

Thanks for any help!

Increment version

Commits were made to fix issue #56, but a version bump wasn't made. I realized I have the latest "version", but didn't have the fix because I use a caching registry. Could we get it bumped?

Restify middleware: HTTP methods mapping is wrong

When DELETE operation is specified in swagger.yaml the Restify middleware tries to invoke app.delete which is not an actual function in Restify (it uses app.del instead). This might be the same for OPTIONS which in Restify is app.opts.

In previous version it was working for iteration was done over Restify's methods and now you are iterating over the methods described in swagger.yaml

As a hack I use app.delete = app.del in my app.js.

Exception stack:

Error in callback! Tossing to global error handler. TypeError: app[method] is not a function
    at registerHandler (/home/api/node_modules/swagger-restify-mw/node_modules/swagger-node-runner/lib/restify_middleware.js:24:18)
    at /home/banzsh/projects/api/node_modules/swagger-restify-mw/node_modules/swagger-node-runner/lib/restify_middleware.js:33:11
    at Array.forEach (native)
    at /home/banzsh/projects/api/node_modules/swagger-restify-mw/node_modules/swagger-node-runner/lib/restify_middleware.js:32:31
    at Array.forEach (native)
    at Middleware.register (/home/banzsh/projects/api/node_modules/swagger-restify-mw/node_modules/swagger-node-runner/lib/restify_middleware.js:30:21)
    at /home/banzsh/projects/api/app.js:76:20
    at /home/banzsh/projects/api/node_modules/swagger-restify-mw/lib/index.js:32:5
    at /home/banzsh/projects/api/node_modules/swagger-restify-mw/node_modules/swagger-node-runner/index.js:234:7

not validating response body

hi i am using swagger-express-mw w

IT looks like swagger validator is not is validating respone body .

_swagger_validate: { name: 'swagger_validator', validateReponse: true },

it looks like there is no use of validateReponse in fittings/swagger-validator.js
can you look at this issue ?

parameter.definition[x-alias]

Hi.

The snippet bellow describes a fitting that allows using in parameters a custom attribute x-alias that helps support API changes concerning parameter names.

The use cases which I get to met a lot, are described as:

Having an API that changed a parameter name
I would like to name in the spec only the official new name
so new users will adhere to the new way

Having an API that changed a parameter name
I would like to be able to decide to support the old name
to help backward compatibility

And the question to you:

Now that we can officially support loading user fittings from node_modules, I may wrap it as a package such as openapi-parameter-alias with it's own tests and all, and let users cherry-pick it into their projects by adding this fitting one step before swagger_validation
Yes, we're ready, lets rock.

OR - alternatively -

No, its too early from your point of view to start diverging modularity, you'd rather it as a PR into bagpipes if at all. In this case, it may not even need to be a separate step. It's a light non-breaking useful feature and same work can be done in fittings/swagger_params_parser.jsaround lines31~41saving an extra loop iteration overswagger.params` per served request.

What are your thoughts about it?

P.S:
the snippet is expressed only as a thought, I did not ran it yet, but I hope the spirit is clear.
it's written in ES6, but it can very easily be put in ES5 if need be, (just replace const for var and handle the destruction and arrows the old way...

const assert = require('assert');
const debug  = require('debug')('fitting:openapi_params_alias');

module.exports = function create(fittingDef) {
    debug('created');
    return openapi_params_alias;
    
    function openapi_params_alias(ctx, cb) {
        debug('exec');
        const req = ctx.request;
        const { params, operation } = req.swagger;
        
        operation.parameterObjects.forEach( parameter  => {
            const name = parameter.name;
            if (parameter.value) {
                debug('value found on official name [%s]', name);
                return;
            }
            
            const alias = parameter.definition['x-alias'];
            if (!alias) {
                debug('no value and no alias for [%s]', name); //if its required - validator will reject it
                return;
            }
            
            const aliasParam = Object.create(parameter, { name: alias });
            const aliasValue = aliasParam.getValue(req).value;
            
            params[name].value = aliasValue;
            debug('value of parameter [%s] was tried and %sfound under alias [%s]', name, aliasValue ? "" : "NOT ", alias, aliasValue);
        });
        
        cb()
    }
}

npm `config` dependency

My application depends upon npm module swagger-express-mw which in turn depends on this project.

This project (swagger-node-runner) depends on npm module config

Since my application also depends on npm module config, I think it's causing a conflict because this config module expects a single configuration directory relative to the current working directory of the process.

The outcome is that when I run the application, I think swagger-node-runner must be reading my application config files instead of the intended config. (swagger-node-runner doesn't report an error)

I might be wrong about swagger-node-runner getting hold of the application config file instead of the intended config file but that's my reasoning based on how the config module works.

Does anyone have any inputs as to what might be happening and the correct way of handling this problem?

btw, Is config needed only to run the swagger editor? Or is it needed by middleware to serve a live API.

express middleware as fitting?

Hey, I have some express middleware I typically use with my express apps, for things like request and error logging. From tidbits I picked up in other issues, I've got it working by deactivating the error handler fitting and adding app.use() statements inside the callback passed in to SwaggerExpress.create().

However, I noticed that you had some experimental code in the bagpipes library that creates a connect-middleware fitting type. I'm interested in the idea of using existing middleware as a fitting, and messed around a bit, modifying index.js in this repo to add a connectMiddlewareDirs property to the pipesConfig object, and otherwise paralleling the logic that produces the value fed into the userFittingsDirs property of that same object.

Though I made some headway, I never got my middleware fully working as a fitting, but before continuing, I figured I should ask about your intentions with that experiment, and whether you think it a good idea to support such a thing over here.

security handlers

EDITED: clarifications added here and there...

I was trying to implement security handlers.

I found the example in the test:

swagger:
    bagpipes:
        _swagger_security:
           name: swagger_security
           securityHandlersModule: api/helpers/securityHandlers

Ok. that's a start.
Imature for my flavor - but still a start.
2 problems are:

  1. What if I want to initiate plummings on server start-up, and fail fast unless I have all I need?
    In the current setup, the server may start accept requests while async initiation is still on progress.
    If the initiation is incomplete - I don't want the server to even join the load-balancer. If there is a problem - I want it to fail fast.
    I want to leave the developer the decision to lazy-load his dependency, but also to let him pull the breaks.
  2. What if I want to wrap handler of each method in it's own package, and let my developers cherry-pick them to their micro-services?

So I thought to create a PR that will accept multiple modules and consolidate them together to the securityHandlers collection.

Something Like that:

swagger:
    bagpipes:
        _swagger_security:
            name: swagger_security
            securityHandlers: 
                basic: openapi-seciruty-myorg-basic
                oauth: openapi-seciruty-myorg-oauth
                req-ip: openapi-seciruty-myorg-req-ip

Keys are types matching api.securityDefinitions like the openapi spec demonstrates.
About values - I thought to let them be

  • require module names, Expecting each module to export a factory(config, cb) that yields a handler(req,res,cb) or handler(req,def,keyOrScope,cb), pre-loaded once on server-startup.
    If he wants to yield the handlers right away and implement deferring internally - it's his decision.
    He can also not yield until all peers are connected.
    In this case, the configs of these modules should be found on config, as siblings to swagger, or as siblings to bagpipes, I have not decided yet.
  • pipe-names, that expect (fittingDef,bagpipes) like any pipe, and return a fitting. The pipe will reject a context by nexting an Error with all rejection-info loaded on it, and accept a context by nexting a null. I assume the error will end up with the error_json_handler. The pipe may enrich the context with more data like middlewares often enrich request objects with user data or roles collection.

These are were the early thoughts.

So I thought to have a look inside and see where it takes me.
I opened fitting/swagger_security, which calls yet again for double-checking with you...

It seems like it wants to support:

swagger:
    bagpipes:
        ...
    securityHandlers: 
       <but what's here? I have no idea> 

After reading the code it looks to me that if config.swagger.securityHandlers is present - no security handlers are loaded...

  1. What am I missing? really... 😲
  2. What are your thoughts about the ideas above?

Error and attempted 404 after sending swagger spec

If you use a swagger_raw pipe to send out the swagger spec when mediated by connect_middleware, the request processing continues after the response has been sent. This eventually leads to express's default 404 handler kicking in, which in turn produces an error when it attempts to set the status code header for a response that has already been sent.

Specifically, the commit ac6dad9 needs to be reverted. It's not clear what problem it's attempting to solve, so I can't say what the impact is, but whatever it's trying to do, this manner of doing it breaks express's contact.

Stack trace:

Error: Can't set headers after they are sent.
  at ServerResponse.OutgoingMessage.setHeader (http.js:690:11)
  at ServerResponse.res.setHeader (/development-source/web/node_modules/express/node_modules/connect/lib/patch.js:63:22)
  at next (/development-source/web/node_modules/express/node_modules/connect/lib/proto.js:156:13)
  at /development-source/web/node_modules/express/lib/application.js:121:9
  at next (/development-source/web/node_modules/express/node_modules/connect/lib/proto.js:129:23)
  at /development-source/web/node_modules/express/lib/application.js:121:9
  at next (/development-source/web/node_modules/express/node_modules/connect/lib/proto.js:129:23)
  at [object Object].finishConnect (/development-source/web/node_modules/swagger-node-runner/lib/connect_middleware.js:94:13)
<snip...>

Connect Middleware ignores res.status set in controller when using res.json

The HTTP status code in res.json is set always set to 200. It should be possible to set a different code within the controller, though. Removing line 220 in connect_middleware.js (res.statusCode = 200) solves the issue without having any negative effect (as far as I see).

So... am I missing a sideeffect/wanted behavior or should the line be removed?

Cheers.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.