apidevtools / swagger-express-middleware Goto Github PK
View Code? Open in Web Editor NEWSwagger 2.0 middlware and mocks for Express.js
Home Page: https://apitools.dev/swagger-express-middleware
License: MIT License
Swagger 2.0 middlware and mocks for Express.js
Home Page: https://apitools.dev/swagger-express-middleware
License: MIT License
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:
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?
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:
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?
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
If swagger's basepath is / and an endpoint is /some/api/endpoint, then one must access the url as //some/api/endpoint otherwise paths won't match.
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);
In CRUD GET over a collection the query params offset and limit are usually used to control pagination.
For example, limit is in the example for http://swagger.io/specification/#parametersDefinitionsObject
swagger-express-middleware seems to handle offset=0 as a search for resources if the field offset having the value 0.
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.
There are three types of mock responses:
object
, array
, undefined
file
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
?
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
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.
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?
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:
I need different multer options for this two endpoints, how should i use swagger-express-middleware to apply different multer options?
There's a bunch of PR and last commit was months ago.
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?
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.
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)
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 "payload" body parameter is invalid ({"test":"lol"})
<br>Maximum call stack size exceeded
<br> at ono (/node_modules/swagger-express-middleware/node_modules/ono/lib/index.js:62:17)
<br> at parseParameter (/node_modules/swagger-express-middleware/lib/param-parser.js:146:11)
<br> at /node_modules/swagger-express-middleware/lib/param-parser.js:93:18
<br> at Array.some (native)
<br> at parseBodyParam (/node_modules/swagger-express-middleware/lib/param-parser.js:77:10)
<br> at Layer.handle [as handle_request] (/node_modules/express/lib/router/layer.js:95:5)
<br> at trim_prefix (/node_modules/express/lib/router/index.js:312:13)
<br> at /node_modules/express/lib/router/index.js:280:7
<br> at Function.process_params (/node_modules/express/lib/router/index.js:330:12)
<br> at next (/node_modules/express/lib/router/index.js:271:10)
<br>
<br>RangeError: Maximum call stack size exceeded
<br> at Function.isArray (native)
<br> at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1334:13)
<br> at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
<br> at normSchema (/node_modules/swagger-express-middleware/node_modules/tv4/tv4.js:1344:6)
Here's npm ls
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.
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
Hello guys,
Is there any way to return a 404 error defined in schema instead the error trace?
Thanks!
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=
).
I have two URL templates:
/api/series/{id}
--> id
is a string and uniquely identifies a series
/api/series/{seriesCollectionId}
--> seriesCollectionId
is 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
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:
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
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?
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?
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:
Resource
(breaking change)DataStore
(breaking change)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?
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.
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.
Body parser within swagger-express-middleware is not able to process the form data as json after it has gone through bodyparser as raw type.
Right now, Swagger Express Middleware focuses on providing mock implementations rather than mock data, but there's no reason it couldn't do both. It already does a little bit of mock-data generation to set HTTP headers and to assign unique IDs when new resources are created, but ideally the DataStore class would have the ability to automatically populate itself fully with mock data based on the JSON Schemas defined in the Swagger API.
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!
Something along these lines would be great in which both rest calls and calls via web sockets that are dispatched to swagger would be great.
See, for example:
https://github.com/jhthorsen/swagger2/blob/master/examples/websocket.pl
https://metacpan.org/pod/distribution/Swagger2/lib/Swagger2/Guides/WebSocket.pod
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:
All in all, to compare the request schema (expected in the POST) to the item schema is 100%.
Please advise,
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?
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...
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.
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
.
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.
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)?
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?
it would be great if errors would be extended with additional properties (e.g. which params where missing)
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.
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?
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?
If you have an endpoint that's expected to deliver a response of some kind, and no response is given, the middleware will fail the request with a 404, implying that the endpoint itself does not exist.
I find this misleading and confusing. Perhaps a 500 (or maybe a 204??) is more appropriate with a log message explaining why.
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.
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.
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.
I'm trying to mock out this api definition,
https://github.com/deardooley/agave-mock-tags-api/blob/master/tags.yaml
But I can't access any routes, persist any data, or do much of anything other than serve up the swagger doc itself. Any idea what could be going on? I tried with both node server samples.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.