Git Product home page Git Product logo

swagger-express-middleware's People

Contributors

aramzs avatar elgalu avatar jamesacres avatar jamesmessinger avatar joshuajabbour avatar jphenow avatar mjhm avatar owenbrotherwood avatar penx avatar philsturgeon avatar rkrauskopf avatar sedgewickmm18 avatar stevenewhouse avatar winniehell 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  avatar  avatar  avatar

swagger-express-middleware's Issues

Integer path parameter with value '0' not converted to number

I was able to reproduce this fairly easily. My swagger doc defines a path parameter which is of type integer but not bounded (no min/max). When feeding a positive integer into the path, I will get: typeof req.params.myparam === number
However, if I feed in a 0 value, I will get: typeof req.params.myparam === string

This is without any change to code. The following middleware are in the process pipeline ahead of my route handler:

  • metadata
  • CORS
  • files
  • validateRequest
  • parseRequest
  • [my route handler]

Is there a simple way to override the automatic primary key detection?

Hi,

I stumbled over your project today and really like it! Good work!

I just got one issue I can't get to work.
I got a nested data structure like: A > B
Both A and B got an attribute called "Oid" as primary key and also a 'name' attribute.
So it is supposed to look like:
/A/{Oid}/B/{Oid}

But since 'Oid' is not in the auto lookup list (https://github.com/BigstickCarpet/swagger-express-middleware/blob/master/docs/middleware/mock.md#how-primary-keys-are-determined) the mock middleware pics 'name'

Is there a simple(!) way to specify the PK of a resource?

404 when requesting mock subcollections

I've created a set of mock sample data with primary resources and two subresources populated with data. https://github.com/deardooley/agave-tags-swagger-middleware. I'm able to browse to the primary resources collection and individual resources successfully:

http://localhost:8000/tags
http://localhost:8000/tags/0

I can also reference the subresources by direct link without problem:

http://localhost:8000/tags/0/resources/0
http://localhost:8000/tags/0/pems/Janie86

However I cannot view the subcollections

http://localhost:8000/tags/0/resources
http://localhost:8000/tags/0/pems

Any idea why this could be?

Default/example values when a model definition is present

We are currently implementing a new set of api's and using the swagger spec. Trying to find a quick way for FE devs to have data be mocked while the services are being built. I have found the auto mocking of default values works fine until there is a ref to a defined model.

Ideally, we should be able to define everything, and utilize default or example (ideally example) so we can quickly use the mock middleware without the need to have "temporary" things in the yaml. It's entirely possible I missed something in the documentation. Still ramping up on the spec and these tools.

Also, I've never got "example" to work, only "default."

Thank you for taking a look at my questions.

For default this works:

/pets/{petName}:
    parameters:
      - $ref: "#/parameters/petName"

    get:
      description: Returns a pet by name
      operationId: findPetByName
      responses:
        default:
          description: Returns the pet data
          schema:
            default:
              name: "Fido"
              type: "dog"
              age: 9
          headers:
            last-modified:
              type: string
              description: The date/time that the pet was last modified

but this does not:

/pets/{petName}:
    parameters:
      - $ref: "#/parameters/petName"

    get:
      description: Returns a pet by name
      operationId: findPetByName
      responses:
        default:
          description: Returns the pet data
          schema:
            $ref: "#/definitions/pet"
            default:
              name: "Fido"
              type: "dog"
              age: 9
          headers:
            last-modified:
              type: string
              description: The date/time that the pet was last modified

Swagger Validation for File Downloads

Swagger Validation failed for ZIP File Download,

I am trying to write a file download API. It is a stream type for response but it is failing as "Response Validation failed"

My Yaml FIles is like this:

produces:
  - application/zip

/library/getacitemspackage:
  # This is the controller for getting the acitem and all its internal references as a deep package for the seamless delivery
    x-swagger-router-controller: library_get_acitems_package
    # this is a post method verb of the api service call
    post:
      summary: The API does the zip of all the given acitems and brings all the deep copy references packages from the cloud library
      description: The API does the zip of all the given acitems and brings all the deep copy references packages from the cloud library
      operationId: libraryGetAcitemsPackage
      parameters:
        - name: acitemsList
          in: body
          description: The list of all the acitems for which the package needs to be delivered as a zip
          schema:
            type: object
      responses:
        "200":
          description: Success
          schema:            
            type: object
        default:
          description: Error
          schema:
            $ref: "#/definitions/ErrorResponse"

My API code is like this :

            var archive = archiver('zip');          
            var totalAcitemListArray = totalAcitemList.toArray();           
            for (var index = 0; index < totalAcitemListArray.length; index++) {
                archive.append(fs.createReadStream(path.join(root_directory, totalAcitemListArray[index])), { name:totalAcitemListArray[index] });
            }           
            archive.finalize();
            archive.on('error', function(err) {
                response.status(500).send({error: err.message});
            });
            response.send('acitemsPackage.zip');            
            archive.pipe(response);

How does one use JSON with swagger-express-middleware?

I am struggling to get this tool to work using JSON. I feel perhaps I am not doing it correctly.

swagger-express-middleware version: 1.0.0-alpha.12

The error I always get is:

WARNING! Unable to find a Swagger path that matches "/admin/aliases"
  swagger:middleware Client requested path "/admin/aliases", which is not defined in the Swagger API. Returning HTTP 404 (Not Found) +0ms
Error: Resource not found: /admin/aliases
    at ono (/home/adowgail/workspace.otif-admin-uis/otif-app-api-admin-ui/node_modules/ono/lib/index.js:62:17)
    at http404 (/home/adowgail/workspace.otif-admin-uis/otif-app-api-admin-ui/node_modules/swagger-express-middleware/lib/request-validator.js:97:11)
    at Layer.handle [as handle_request] (/home/adowgail/workspace.otif-admin-uis/otif-app-api-admin-ui/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/adowgail/workspace.otif-admin-uis/otif-app-api-admin-ui/node_modules/express/lib/router/index.js:312:13)
    at /home/adowgail/workspace.otif-admin-uis/otif-app-api-admin-ui/node_modules/express/lib/router/index.js:280:7
    at Function.process_params (/home/adowgail/workspace.otif-admin-uis/otif-app-api-admin-ui/node_modules/express/lib/router/index.js:330:12)
    at next (/home/adowgail/workspace.otif-admin-uis/otif-app-api-admin-ui/node_modules/express/lib/router/index.js:271:10)
    at http401 (/home/adowgail/workspace.otif-admin-uis/otif-app-api-admin-ui/node_modules/swagger-express-middleware/lib/request-validator.js:84:3)
    at Layer.handle [as handle_request] (/home/adowgail/workspace.otif-admin-uis/otif-app-api-admin-ui/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/home/adowgail/workspace.otif-admin-uis/otif-app-api-admin-ui/node_modules/express/lib/router/index.js:312:13)

But using swagger-parser seems to work fine:

{ swagger: '2.0',
  info: 
   { description: 'foobar',
     version: '1.0.0',
     title: 'foobar',
     termsOfService: '',
     contact: 
      { name: 'Foo',
        url: 'http://www.foobar.com',
        email: '[email protected]' },
     license: { name: 'Foobar', url: 'http://www.foobar.com/foobar.html' } },
  basePath: '/',
  tags: [ { name: 'Aliases' } ],
  paths: { '/admin/aliases': { get: [Object] } },
  definitions: { aliases: { type: 'object', properties: [Object] } } }

This is my little swagger app:

process.env.DEBUG = 'swagger:middleware';

var express = require('express');
var middleware = require('swagger-express-middleware');
var path = require('path');
var app = express();

var fs = require('fs');

var swaggerJson = 'integration-tests/fixtures/swagger2.json';

middleware(swaggerJson, app, function(err, middleware) {
    if (err) {
        console.log('ERROR');
        console.log(err);
        return;
    }   

    app.use(
        middleware.metadata(),
        middleware.files(),
        middleware.parseRequest(),
        middleware.validateRequest(),
        middleware.mock()
    );  

    app.listen(8001, function() {
        console.log('Swagger service running');
    }); 
});

And my super basic swagger json file:

{
  "swagger" : "2.0",
  "info" : {
    "description" : "foobar",
    "version" : "1.0.0",
    "title" : "foobar",
    "termsOfService" : "", 
    "contact" : { 
      "name" : "Foo",
      "url" : "http://www.foobar.com",
      "email" : "[email protected]"
    },  
    "license" : { 
      "name" : "Foobar",
      "url" : "http://www.foobar.com/foobar.html"
    }   
  },  
  "basePath" : "/",
  "tags" : [ { 
    "name" : "Aliases"
  }], 
  "paths" : { 
    "/admin/aliases" : { 
      "get" : { 
        "tags" : [ "Aliases" ],
        "summary" : "Retrieve aliases.",
        "description" : "", 
        "operationId" : "getConfig",
        "consumes" : [ "application/xml", "application/json" ],
        "produces" : [ "application/xml", "application/json" ],
        "responses" : { 
          "200" : { 
            "description" : "Normal response",
            "schema" : { 
              "$ref" : "#/definitions/aliases"
            }   
          }   
        }   
      }   
    }   
  },
  "definitions" : { 
    "aliases": {
        "type": "object",
        "properties": {
            "value": {
                "type": "string",
                "description": "some string",
                "default": "foobar"
            }
        }
    }
  }
}

I'm not sure why it thinks /admin/aliases is an invalid path and I suspect I'm loading the json file incorrectly.

Remove restriction on Content-Type for primitive type responses

There are three types of mock responses:

  • object, array, undefined
  • file
  • the rest

Namely "the rest" according to swagger specification are all primitive types allowed by JSON schema (boolean, integer, number. string).

Current behavior is to disallow JSON and application/octet-stream for those primitive types. I don't see where this restriction comes from. Responses like true, 43 or "foo" are valid JSON to my knowledge and parse correctly using JSON.parse(). They are also valid for application/octet-stream.

Can we leave such restrictions to produces?

Does not convert date-time strings to Date objects if using Swagger composition (allOf)

The Swagger spec supports some concept of composition via keywords like allOf (see the section "Composition and Inheritance (Polymorphism)" under Schema Object).

However, SEM does not correct handle [at least] converting the input for such definitions into their appropriate data types, at least for strings with a format: date-time.

For example, the following schema works with SEM and correctly converts the property "timeStart" into a Date object when the body schema is $ref: '#/definitions/TraceParametersBasic':

definitions:
  TraceParametersBasic:
    required:
      - timeStart
    properties:
      timeStart:
        type: string
        format: date-time

However, if we use schema composition to make a more complex object that consumes that basic schema, neither of the properties "timeStart" nor "timeEnd" will be converted to Date objects when the body schema is $ref: '#/definitions/TraceParametersEnhanced':

definitions:
  TraceParametersBasic:
    required:
      - timeStart
    properties:
      timeStart:
        type: string
        format: date-time
  TraceParametersEnhanced:
    allOf:
      - $ref: '#/definitions/TraceParametersBasic'
      - type: object
        required:
          - timeEnd
        properties:
          timeEnd:
            type: string
            format: date-time

Upgrade multer

Looking through the code, I noticed a piece of code that was commented out because it was waiting for a bug to be fixed. It appears that bug is fixed. If there are tests that to integration tests around file uploading, I can submit a PR fixing this.

Response body validation of mocks

It appears as though I can set my mocks to be any data structure, and the response will be served without validating against the swagger file's response schema for the path.

For example, if my /users/:id endpoint had the following response schema:

{
  title: 'User',
  description: 'User description.',
  type: 'object',
  properties: {
    userId: {
      description: 'account id',
      type: number
    }
  },
  required: ['userId'],
  additionalProperties: false
};

I can still add the following mocks for the path, and they are served regardless of the fact that the data structure is missing userId, and has additional properties:

let myDB = new MemoryDataStore()
let invalidResponse = { foo: "bar" };
myDB.save(new Resource('/users/1', invalidResponse))

To me, enforcing accurate responses is one of the most important potential value-adds, so this feels like a gap to me. Thoughts on adding a json-validator around the mock middleware, or perhaps I'm missing something?

How to use multer with different config for different API endpoints?

I can't figure out how to use multer (from request parser) with different options on different API endpoints.

Let's say we have following API endpoints:

  • POST /images
  • POST /documents

I need different multer options for this two endpoints, how should i use swagger-express-middleware to apply different multer options?

Router middleware to dispatch based on operationId

It would be nice to have a router middleware that would simplify the creation of handlers for methods based on the operationId.

The idea would be as follows.

Based on the following snippet

/pets:
    get:
      summary: List all pets
      operationId: listPets

one would create an object and use something like the following snippet to create the router.

var petrouter = {
    listPets: function(req, res, next) {
        // Do something
    }
};
app.use(middleware.router(petrouter));

Instead of having to the the following for ever method defined in the specification file

app.patch('/pets', function(req, res, next) { 
    // Do something
});

The advantage I see would be that the redundancy between what method to use (GET, PUT, ...) and the exact path specification could be avoided. The only thing that maps between the swagger spec and the implementation is the operationId.

What do you think? Would this be a sensible enhancement?

Example values are populated into requests when property is empty string

Here is an example app:

var express = require('express');
var swagger = require('swagger-express-middleware');
var request = require('request');

var app = express();

swagger({
  swagger: '2.0',
  info: {
    version: '1.0',
    title: 'Bug'
  },
  consumes: [
    'application/json'
  ],
  paths: {
    '/': {
      post: {
        parameters: [{
          name: 'payload',
          in: 'body',
          required: true,
          schema: {
            $ref: '#/definitions/Node'
          }
        }]
      }
    }
  },
  definitions: {
    Node: {
      type: 'object',
      properties: {
        name: {
          type: 'string',
          example: 'should not see'
        },
      }
    }
  }
}, app, function(err, middleware) {

  app.use(
    middleware.metadata(),
    middleware.parseRequest(),
    middleware.validateRequest(),
    function (req, res, next) {
      res.status(200).json(req.body).end();
    }
  );

  app.listen(8000, function() {
    request({
      url: 'http://localhost:8000',
      method: 'POST',
      body: { name: '' },
      json: true,
    }, function(err, res, body) {
      console.log(body);
    });
  });
});

This logs

{ name: 'should not see' }

When it should log the value posted:

{ name: '' }

This example value is coming from getValueToValidate in lib/helpers/json-schema.js.
Where if you pass an empty string then it returns the example data and updates the value.

This makes perfect sense for default value but not example value.

submodules

hi i am having trouble applying swagger-express to my application with submodules.

apparently the metadata is not including req.baseUrl when calculation their position (or respectively using originalUrl instead)

Maximum call stack size exceeded when validating recursive models

Running this

var express = require( 'express' );
var swagger = require( 'swagger-express-middleware' );
var request = require( 'request' );

var app = express();

swagger( {
  swagger: '2.0',
  info: {
    version: '1.0',
    title: 'Bug'
  },
  consumes: [
    'application/json'
  ],
  paths: {
    '/': {
      post: {
        parameters: [
          {
            name: 'payload',
            in: 'body',
            required: true,
            schema: {
              $ref: '#/definitions/Node'
            }
          }
        ]
      }
    }
  },
  definitions: {
    Node: {
      type: 'object',
      properties: {
        name: {
          type: 'string'
        },
        child: {
          $ref: '#/definitions/Node'
        }
      }
    }
  }
}, app, function ( err, middleware ) {

  app.use(
    middleware.metadata(),
    middleware.parseRequest(),
    middleware.validateRequest()
  );

  app.listen( 8000, function() {

    request( {
      url: 'http://localhost:8000',
      method: 'POST',
      headers: {
        'Content-type': 'application/json'
      },
      body: JSON.stringify( {
        name: 'lol'
      } )
    }, function ( err, res, body ) {
      console.log( err, body );
    } );

  } );

} );

results in

Error: The &quot;payload&quot; body parameter is invalid ({&quot;test&quot;:&quot;lol&quot;}) 
<br>Maximum call stack size exceeded
<br> &nbsp; &nbsp;at ono (/node_modules/swagger-express-middleware/node_modules/ono/lib/index.js:62:17)
<br> &nbsp; &nbsp;at parseParameter (/node_modules/swagger-express-middleware/lib/param-parser.js:146:11)
<br> &nbsp; &nbsp;at /node_modules/swagger-express-middleware/lib/param-parser.js:93:18
<br> &nbsp; &nbsp;at Array.some (native)
<br> &nbsp; &nbsp;at parseBodyParam (/node_modules/swagger-express-middleware/lib/param-parser.js:77:10)
<br> &nbsp; &nbsp;at Layer.handle [as handle_request] (/node_modules/express/lib/router/layer.js:95:5)
<br> &nbsp; &nbsp;at trim_prefix (/node_modules/express/lib/router/index.js:312:13)
<br> &nbsp; &nbsp;at /node_modules/express/lib/router/index.js:280:7
<br> &nbsp; &nbsp;at Function.process_params (/node_modules/express/lib/router/index.js:330:12)
<br> &nbsp; &nbsp;at next (/node_modules/express/lib/router/index.js:271:10) 
<br>
<br>RangeError: Maximum call stack size exceeded
<br> &nbsp; &nbsp;at Function.isArray (native)
<br> &nbsp; &nbsp;at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1334:13)
<br> &nbsp; &nbsp;at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> &nbsp; &nbsp;at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> &nbsp; &nbsp;at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> &nbsp; &nbsp;at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> &nbsp; &nbsp;at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> &nbsp; &nbsp;at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> &nbsp; &nbsp;at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> &nbsp; &nbsp;at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)

Here's npm ls

Responds to all OPTIONS requests as CORS preflights, even if they are not CORS requests

When enabling the CORS middleware, it inappropriately responds to all HTTP OPTIONS requests as if they were a CORS preflight request -- not just for CORS requests.

Per the CORS spec's "Resource Processing Model" section, requests without the Origin header present are not CORS requests.

This prevents us from responding to normal OPTIONS requests.

NOTE:
This bug could possibly be worked around by registering our OPTIONS route handler middleware ahead of the Swagger middleware but I haven't tested that.

api-docs doesn't seem to work

I was having trouble getting api-docs to work on my prototype, so I tried it out.

With a fresh clone, all tests pass, then I run npm start.

When I try to access the two Swagger API links ( http://localhost:8000/api-docs/PetStore.yaml and http://localhost:8000/api-docs ) I get 404 errors.

Debug output:

 ~/projects/swagger-express-middleware   master  npm start

> [email protected] start /Users/aschamp/projects/swagger-express-middleware
> cd samples && node sample2.js

The Swagger Pet Store is now running at http://localhost:8000
  swagger:middleware GET / matches Swagger path / +0ms
  swagger:middleware Validating Accept header (text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8) +8ms
  swagger:middleware Validating Content-Length header (NaN) +4ms
  swagger:middleware Using default (200) response for GET / +1ms
  swagger:middleware Running the queryResource mock +1ms
  swagger:middleware GET / does not exist, but the response schema defines a fallback value.  So, using the fallback value +1ms
  swagger:middleware Setting 0 response headers... +0ms
  swagger:middleware Using text/html MIME type, which is allowed by the Swagger API +10ms
  swagger:middleware Sending raw buffer data +0ms
WARNING! Unable to find a Swagger path that matches "/favicon.ico"
  swagger:middleware Client requested path "/favicon.ico", which is not defined in the Swagger API. Returning HTTP 404 (Not Found) +803ms
WARNING! Unable to find a Swagger path that matches "/api-docs"
  swagger:middleware Client requested path "/api-docs", which is not defined in the Swagger API. Returning HTTP 404 (Not Found) +5s
WARNING! Unable to find a Swagger path that matches "/api-docs/PetStore.yaml"
  swagger:middleware Client requested path "/api-docs/PetStore.yaml", which is not defined in the Swagger API. Returning HTTP 404 (Not Found) +7s
WARNING! Unable to find a Swagger path that matches "/api-docs/PetStore.yaml"
  swagger:middleware Client requested path "/api-docs/PetStore.yaml", which is not defined in the Swagger API. Returning HTTP 404 (Not Found) +2m
WARNING! Unable to find a Swagger path that matches "/api-docs"
  swagger:middleware Client requested path "/api-docs", which is not defined in the Swagger API. Returning HTTP 404 (Not Found) +723ms

parseRequest middleware does not allow empty array parameters

The parseRequest middleware does not allow empty arrays for specified parameters (e.g. /foo?username=), even when such a parameter's schema includes required: false and/or minItems: 0.

Error: The "username" query parameter is invalid ("")
JSON Schema validation error.
Invalid type: string (expected array)
    at ono (c:\git\Observer\Apps\ObsNode\node_modules\ono\lib\index.js:62:17)
    at parseParameter (c:\git\Observer\Apps\ObsNode\node_modules\swagger-express-middleware\lib\param-parser.js:148:11)
    at c:\git\Observer\Apps\ObsNode\node_modules\swagger-express-middleware\lib\param-parser.js:35:35
    at Array.forEach (native)
    at parseSimpleParams (c:\git\Observer\Apps\ObsNode\node_modules\swagger-express-middleware\lib\param-parser.js:30:12)
    at ...

However, as I understand it from OAI/OpenAPI-Specification#305 and APIDevTools/swagger-parser#6, this should result in [].

I can temporarily workaround the problem by adding default: [] to the schema but that also sets the parameter to [] even if it was not specified at all (i.e. for both /foo and /foo?username=).

URL templates with different placeholder types

I have two URL templates:

/api/series/{id} --> idis a string and uniquely identifies a series
/api/series/{seriesCollectionId} --> seriesCollectionIdis an integer and identifies a collection of series

SEM always identifies the first template as the correct one even if a pass a string (SEM doesn't take the type into account). This results is Error: The "id" path parameter is invalid

Question: is there an easy way to work with json API specs?

Hi there! First thanks a lot for the great piece of software :)

I'm playing around with it and ask me one big question.
Is it possible to work with the format of JSON API Specs with this extension?
Or do I have to customise the source or add some functions to hooks?
Maybe I've overlooked something, or this feature just doesn't exist yet.

According to the examples of jsonapi.org i think there is a difficulty at data storing.
If you compare the POST and GET examples below, you'll see the difference.
In the POST Request the single object "data" contains the data for itself.
But for the GET Response, this object is in an array (also named "data).

I've tried two ways:

  1. Send Post as below and look at the GET response --> There is no array, single object "data" replaces the storage at each POST
  2. At GET response, wrap the single Object with the data array --> works fine for a valid GET response, but then I've to remove the data object at POST which isn't valid according to JSON API

Example for POST:

POST /photos HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

{
  "data": {
    "type": "photos",
    "attributes": {
      "title": "Ember Hamster",
      "src": "http://example.com/images/productivity.png"
    }
  }
}

Example for GET (after 2 POST executions):

HTTP/1.1 200 OK
Content-Type: application/vnd.api+json

{
  "links": {
    "self": "http://example.com/photos"
  },
  "data": [{
    "type": "photos",
    "id": "1",
    "attributes": {
      "title": "Ember Hamster",
      "src": "http://example.com/images/ember-hamster.png"
    }
  }, {
    "type": "photos",
    "id": "2",
    "attributes": {
      "title": "GitHub Cat",
      "src": "http://example.com/images/github-cat.png"
    }
  }]
}

I would be happy if someone just can answer my question. So I know if I'm searching my solution in the right direction :)

Thanks a lot!
Jonas

Getting just validation errors messages - without whole error stack messages

How can I respond with proper JSON containing validator errors?

I'm using parseRequest middleware, the error I'm catching has proper status property for validation errors (400), but when I'm about to inform API consumer what exactly went wrong I have only the error message string with concatenated all errors messages in stack:

The \"newFloorPlan\" body parameter is invalid ({\"name\":\"string\",\"number\":0,\"width\":12,\"height\":12,\"backgroundImage\":\"string\",\"backgroundScale\":0,\"backgroundLocalNorthCoordinate\":123323,\"backgroundLocalEastCoordinate\":12}) 
JSON Schema validation error.
Data path: \"/backgroundLocalNorthCoordinate\" 
Schema path: \"/properties/backgroundLocalNorthCoordinate/maximum\" 
Value 123323 is greater than maximum 32767

I don't want to expose all the details to API consumer, I just need to expose input data errors, f.e:

[
  {property: "backgroundLocalNorthCoordinate", message: "Value 123323 is greater than maximum 32767" 
]

Is it possible?

Is there any way to set global responses or CORS

My GET POST requests are changed to OPTIONS by CORS preflight.
Cause my request is cross-domain, header-setted and with-credentials.

I've searched a lot to solve this problem, but failed.

Thus, I gave up to avoid this and try to make my request allow OPTIONS.

But I only found it able to set options for every path.
I've also tried to use regexp to match all path, which seems not supported yet.

Is there any way to set global responses for all path or somethings else to avoid automatically send request by OPTIONS method?

Any ideas?

Support mocking error responses

Resource only depends on the request path and even though the response is picked by status code, the status code is not taken into account when retrieving the response body from data store. This makes it impossible to mock error responses as far as I can see.

There are three ways to change this, in my opinion:

  1. add the status code to Resource (breaking change)
  2. add the status code to DataStore (breaking change)
  3. introduce an ErrorResource/StatusAwareResource which can be passed to DataStore

Maybe a mix of 1. and 3. is also possible: the status code could be optional part of Resource, i.e. not passed to the constructor.

What do you think?

Correct handling of paths when `basePath` is set in Swagger definition

In my Swagger 2.0 definition, I have

basePath: /api

paths:
  /spinners:
    get: ...
  /spinners/{id}
    parameters: ...
    get: ...

When I do GET http://localhost:3000/api/spinners/0, I receive a 404.

If I comment out the basePath line in the definition, then do GET http://localhost:3000/spinners/0, I get the JSON data for the object (as I've set it in the mocks and datastore).

Based on the debug output, it is parsing the path correctly. However, when it calls get on the datastore, it seems to be passing the full path, /api/spinners/0 as the resource parameter to DataStore.get, instead of removing the base path first.

This is in version 0.4.7, which is the most recent in NPM.

Adds CORS headers to all responses, even if they are not CORS requests

When enabling the CORS middleware, it inappropriately adds CORS-related response headers for ALL requests — not just for CORS requests.

e.g.

$ curl -ki https://localhost/api/v1/about

HTTP/1.1 200 OK
Date: Wed, 16 Mar 2016 15:42:32 GMT
Server: Apache
X-Powered-By: Express
access-control-allow-origin: *
access-control-allow-methods: GET, OPTIONS
access-control-allow-headers:
Access-Control-Allow-Credentials: false
access-control-max-age: 0
Content-Type: application/json; charset=utf-8
Content-Length: 44
ETag: W/"15e-ldRTnVwhpSAI2P0bgpa0Zw"
Vary: Accept-Encoding

{"version":{"major":1,"minor":0,"patch":0}}

Per the CORS spec's "Resource Processing Model" section, requests without the Origin header present are not CORS requests.

Auto-checking request body against Swagger JSON schema

Since the Swagger spec supports JSON schemas for req.body, I expected the Validate Request middleware to use this to test incoming request bodies, and emit a (customizable) HTTP 4xx code on error. But that seems not to be the case?

If I am mistaken, please let me know how to enable this functionality. Otherwise, consider this a feature request.

In any case, thanks for these fantastic tools!

problem identifying collection versus resource

I noted my swagger mock was failing cause it was using query resource where query collection should be be used. My collection look like {offset=0, limit=10, items: [], etc)

The problem, as far as I can tell, lies in SemanticResponse.prototype.setWrapperInfo
There they compare if the schema for the payload sent to POST matches the schema for the object described for the elements in items.

In my case that does work, two classic examples:

  1. For resources that have server-generated IDs, the POST forbids the payload to include an attribute "id", the GET returns the "id" in the payload
  2. In the POST, the payload does not have the "links" section, in the GET it does.

All in all, to compare the request schema (expected in the POST) to the item schema is 100%.

Please advise,

cannot retrieve all records using GET /, but single record is retrieved /{path-id}

Hi,
based on sample2, I tried to pre-populate data for my API

  var myDB = new MemoryDataStore();
  myDB.save(
  new Resource('/authorizations/123', {name: xxxx', desc: 'xxxx'}),
  new Resource('/authorizations/456', {name: 'xxxxx', desc: 'xxxx'}),
  new Resource('/authorizations/789', {name: 'xxxx', desc: 'xxxx'}),
  new Resource('/authorizations/100', {name: 'xxxxx', desc: 'xxxx'})
    ); 

I am able to retrieve single record when I run a
GET /authorizations/123
but
GET /authorizations
brings back 404.
While in sample2 GET /pets brings back all records.
In my Spec file, both /authorizations and /authorization/{auth-id} are of type object. Any ideas what might be causing this?

How i can add new format validation?

In spec 2.0 for strings have 5 build-in formats: password, date, date-time, binary and byte
But it is also written that: "However, the format property is an open string-valued property, and can have any value to support documentation needs. Formats such as "email", "uuid", etc., can be used even though they are not defined by this specification."

I want add email validation. Library tv4 have method ValidatorContext.prototype.addFormat,
which can be used for that, but "swagger-express-middleware" can't yet use user-defined formats...

Using Multiple swagger files and supporting multiple swagger based micro-services

We have a simple mock server implementation based on swagger-express-middleware:

var myDB = new FileDataStore('.rest-db');
var definitionsPath = 'src/swagger/specifications';
app.use(express.static('www'));
fs.readdir(definitionsPath).forEach(function(filename){
    console.log("Setting up mock services for "+definitionsPath+'/'+filename);
    middleware(definitionsPath+'/'+filename,app, function(err,middleware){
        app.use(
            middleware.files(),
            middleware.metadata(),
            middleware.parseRequest(),
            middleware.validateRequest(),
            middleware.mock(myDB)
        );
    });
});

We have found that this implementation does not work as the first swagger file blocks further references to swagger files further down the chain, by returning 404 errors.

Problems when basePath is "/"

Hey there,

In a swagger.json file, I consume with the swagger-express-middleware there is an entry "basePath": "/" which causes the endpoints to break. I assume that it appends the / from basePath to other URLs resulting in invalid URLs like //foobar.

How can i pass by mock middleware resources filtering?

I have some required query params like a offset and limit. And i doesn't have this fields in my resources, but filtering apllies to them and i get empty array in response for every request.
How can I pass by filter?

  swagger:middleware Filtering resources by {"offset":0,"limit":10} +1ms
  swagger:middleware 0 resources matched the filter criteria +4ms

I use swagger-express-middleware as part of swagger-server.

Session sensitive data store?

So here is my problem, I am using this tool as part of my selenium testing. For each browser, I would like a separate data store so that actions performed by one browser do not affect the other.

I did not see anything in the documentation to support such a use case. If it's not supported out of the box, then I'd like to wonder out loud how it can be done.

Perhaps it's possible to assign a unique cookie, have all keys in the data store be prefixed by the value of that cookie (transparently)?

Can swagger-express-middleware mock based on example response?

First of all, I am thankful such project exists.

My response definition looks like this-

        "responses": {
          "200": {
            "description": "successful operation",
            "schema": {
              "type": "array",
              "items": {
                "$ref": "#/definitions/Account"
              }
            },
            "examples": {
              "application/json": [
                {
                  "id": 123,
                  "name": "dev-account"
                },
                {
                  "id": 456,
                  "name:": "prod-account"
                }
              ]
            }
          }
        }

When using swagger-express-middleware I was hoping that when I make API call I will get example response back but I get back an empty array. What can I do to make sure I get example response back?

validator error

it would be great if errors would be extended with additional properties (e.g. which params where missing)

If a name property is inherited, getResourceNameByName will fail

If a name property is inherited (for example, id is inherited from a parent type) then the lookup that attempts to identify the name of the resource fails with the following:

TypeError: Cannot read property 'id' of undefined
    at ./node_modules/swagger-express-middleware/lib/mock/edit-collection.js:226:28
    at Array.some (native)
    at getResourceNameByName (./node_modules/swagger-express-middleware/lib/mock/edit-collection.js:219:35)
    at getResourceName (./node_modules/swagger-express-middleware/lib/mock/edit-collection.js:150:9)
    at createResources (./node_modules/swagger-express-middleware/lib/mock/edit-collection.js:115:20)
    at mergeCollection (./node_modules/swagger-express-middleware/lib/mock/edit-collection.js:36:19)
    at mockImplementation (./node_modules/swagger-express-middleware/lib/mock/index.js:125:7)
    at Layer.handle [as handle_request] (./node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (./node_modules/express/lib/router/index.js:312:13)
    at ./node_modules/express/lib/router/index.js:280:7

as it attempts to find id directly in the property list, however, the id is listed via a nested reference.

Validate path parameters?

Is there validation of parameter data? Right now, if I have this spec:

  /pets/{id}:
    parameters:
      - name: id
        in: path
        description: Resource ID
        required: true
        type: integer
        format: int32
    get:
      description: Finds a pet by ID
      operationId: findPetById
      responses:
        default:
          description: Returns the pet data
          schema:
            $ref: pet

when using an invalid URL I get: swagger:middleware GET /pets/abc matches Swagger path /pets/{id} which is definitely not true.

Is this just something that hasn't been implemented yet? Or am I missing it?

Plugin logic how to handle query params?

First of all thank you for providing this great framework!

It looks like swagger-express-middleware just applies query string parameters as filter for existing fields. However I would like to apply my own logic (e.g. priority=high should return all items of a collection where some condition is fulfilled). Can I do this?

Add new middleware to handle non-CORS OPTIONS requests

I'd like to see a new middleware added to handle non-CORS OPTIONS requests by responding 200 OK with an Allow response header detailing which HTTP methods are supported for that path.

This should be easy to add as that same logic is already used to construct the Access-Control-Allow-Methods response header in the CORS middleware today: lib/cors.js#L50-L53

This new middleware should only end the response if there isn't an actual OPTIONS route configured in the associated Swagger spec. It should add the Allow response header no matter what, though.

Request body validated not according to Swagger 2.0 spec.

According to spec swagger inside schema object support only limited subset of JSON Schema draft4 and extend it with custom keywords.

So, you don't use "discriminator" and "readOnly" keywords during validation that mean you don't fully support Swagger 2.0 spec.

Personally, I think it's a problem in Swagger spec.
So I created OAI/OpenAPI-Specification#333 feature request to make Swagger compatible with JSON Schema.
And I want library authors took part in that discussion.

Using swagger-express-middleware on router do not match api base patch

I have a base app (it is doing static content serving and other common tasks)

var app = express();

and a router for api mounted on /api/v2

var apiRouter = new express.Router();
app.use('/api/v2', apiRouter);

and the basePath in my swagger.json is basePath: "/api/v2"

When I'm installing swagger-express-middlerwares on the apiRouter the metadata middleware do not match any of incoming requests.

request-metada.js:33

      var basePath = util.normalizePath(context.api.basePath, router); //this resolves to "/api/v2"
      var reqPath = util.normalizePath(req.path, router); //this resolves to "/floor-plans" for a http post localhost/api/v2/floor-plans
      if (_.startsWith(reqPath, basePath)) {
        req.swagger.api = context.api;
      }

It works ok when I install swagger on the main app.

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.