swagger-api / swagger-node Goto Github PK
View Code? Open in Web Editor NEWSwagger module for node.js
Home Page: http://swagger.io
License: Apache License 2.0
Swagger module for node.js
Home Page: http://swagger.io
License: Apache License 2.0
This code apparently works with the git version of swagger-node-express (version 1.3.0) but doesn't work with the npm version (1.2.3). Since I am intending to distribute my package through npm and automatically install swagger-node-express as a dependency, is there any way to make this code work with the older version of the package on npm?
Sample code is here:
http://pastebin.com/PVaePtKw
Hi there,
I wanted to know what is the less intrusive way to document my API.
I have a large set of existing routes in subfolders, I'm making an intense use of sub application pattern so my logic is split among several files.
Also I have my own error handling system, so what will happen if I don't use swagger.errors.*
?
It looks like discoverFile
as some magic that I can use, I just wanted to know if it's the best way.
Last but not least, there is no activity on the master for the past 5 months, is this project still active?
Thanks,
Antoine
Setting a path parameters as not required makes API docs unusable to test with, nothing happens when you click "Try it out". This is how I define my path param:
{
"name" : 'discussionId',
"description" : 'Discussion ID',
"dataType" : 'string',
"required" : false,
"allowMultiple" : false,
"allowableValues" : null,
"paramType" : "path"
}
TypeError: Cannot read property 'void' of undefined
at filterApiListing (/Users/orsa/home/projects/stampup/saturn/server/node_modules/swagger-node-express/Common/node/swagger.js:166:33)
at /Users/orsa/home/projects/stampup/saturn/server/node_modules/swagger-node-express/Common/node/swagger.js:84:20
at callbacks (/Users/orsa/home/projects/stampup/saturn/server/node_modules/express/lib/router/index.js:161:37)
TypeError: Cannot read property 'void' of undefined
at filterApiListing (/Users/orsa/home/projects/stampup/saturn/server/node_modules/swagger-node-express/Common/node/swagger.js:202:35)
at /Users/orsa/home/projects/stampup/saturn/server/node_modules/swagger-node-express/Common/node/swagger.js:84:20
at callbacks (/Users/orsa/home/projects/stampup/saturn/server/node_modules/express/lib/router/index.js:161:37)
at param (/Users/orsa/home/projects/stampup/saturn/server/node_modules/express/lib/router/index.js:135:11)
at pass (/Users/orsa/home/projects/stampup/saturn/server/node_modules/express/lib/router/index.js:142:5)
Then you can use in any connect app - like restify - Restify is becoming one of the best node modules for creating a REST service - but as this is so tied into express its difficult to implement
I'd be willing to contribute to doing so, if you're open to the idea
"params" : [param.post("Pet", "Pet object that needs to be updated in the store", "{\n "id": 3,\n "category": {\n "id": 2,\n "name": "Cats"\n },\n "name": "Cat 3",\n "urls": [\n "url1",\n "url2"\n ],\n "tags": [\n {\n "id": 3,\n "name": "tag3"\n },\n {\n "id": 4,\n "name": "tag4"\n }\n ],\n "status": "available"\n}")],
This causes the UI to not allow switching between different data types and therefore the request is sent only with Content-Type:application/xml. This then can't be parsed by the middleware and errors with an empty body.
The application I am developing requires two different api definitions that live on different ports. I currently have no way, that I can figure out, to do this with swagger. Effectively I need to create two express applications, but swagger has it's variables defined globally and does not actual have a "Swagger" object. I believe the solution would be to create a Swagger object that has the globals as members. I am still learning Javascript myself so it's beyond my expertise. Further it seems like a huge change...
I have a deep model structure. Working with MongoDb, this in not uncommon.
If main model (present in responseClass) contains another type/array$ref:"subModel", which contains a type/array$ref:"subModel2", the subModel2 models will not be shown in the final api listing .json.
The "requestedModels" array is only added to in one pass, so if there appear subModels, they will not be added.
My solution was to add online 185 (in swagger.js) this line:
for(var i=0;i<=2;i++) {
and close this for in line 222.
Now all my models are displayed.
Pets example works fine, though not the user example. Confirmed mongodb connection is working fine.
Using:
node.js v0.8.8
express 3.0.0rc4
node Apps/user/main.js
API listening on 8002
GET /resources.json?api_key=special-key 200 3ms
TypeError: Cannot read property 'void' of undefined
at applyFilter (/Users/xxxxx/dev/projects/swagger/swagger-node-express/Common/node/swagger.js:214:35)
at /Users/xxxxx/dev/projects/swagger/swagger-node-express/Common/node/swagger.js:56:20
spec
and action
are the only two methods available. How to define routing middlewares like express?
exports.findByStatus = {
'spec': {
// spec ...
},
'action': function (req,res) {
// do something
}
};
Dumping the stack in production isn't ideal. Info leak.
On POST of invalid JSON body a transparent json.parse error was returned as response. Also node threw error:
Error: invalid json
at Object.exports.error (/apiSwagger/node_modules/express/node_modules/connect/lib/utils.js:64:13)
at /apiSwagger/node_modules/express/node_modules/connect/lib/middleware/json.js:73:69
at IncomingMessage.onEnd (/apiSwagger/node_modules/express/node_modules/connect/node_modules/raw-body/index.js:109:7)
l. 42 main.js: express.json()) no more required:
//app.use(express.json());
seemed to do the cure. fixed response body:
{
"code": 400,
"message": "invalid input"
}
There is some confusion around the current best practice for setting defining post/body data. In the 1.2.3 NPM package it shows param.post(). It appears param.post is old and will be replaced everywhere with the param.body() function?
Can we get a new NPM package? I did a boat load of refactoring the wrong direction. I guess I can setup my dependency to use the git HEAD, but I prefer to use a published NPM package.
Thanks for the killer work!
api.formagg.io is better for it.
Swagger doesn't seem to be running with the latest version of Node (v0.6.16). Would love to see Swagger updated! :-)
I am not sure if this is issue with this module or the ui, but I am posting it here. I have three actions for one resource and I have a problem with one of them. Two others work without any problem, but this one keeps giving me following error:
XMLHttpRequest cannot load http://localhost:8002/topic/findAll/1/2. Origin http://localhost is not allowed by Access-Control-Allow-Origin."
this is my resource:
exports.findAll = {
'spec': {
"path" : "/topic/findAll/{offset}{limit}",
"notes" : "Offset and limit",
"summary" : "Get topics list from given integer offset and limited by given integer limit",
"params" : new Array(
swagger.pathParam("offset", "Offset", "string"),
swagger.pathParam("limit", "Limit", "string")
),
"outputModel" : {
"name" : "List[topic]",
"responseClass" : watsonModels.topic
},
"errorResponses" : new Array(
swagger.error(400, "Invalid limit or offset value"),
swagger.error(404, "Topic not found")
),
"nickname" : "findAll"
},
'action': function (req,res) {
console.log('get list');
var offset = parseInt(url.parse(req.url,true).query["offset"]);
if (!offset) {
throw swagger.error(400, "invalid offset supplied"); }
var limit = parseInt(url.parse(req.url,true).query["limit"]);
if (!limit) {
throw swagger.error(400, "invalid limit supplied"); }
var output = new Array();
for (var i = 0; i < swagger.Randomizer.intBetween(1,limit); i++) {
output.push(swagger.containerByModel(watsonModels.topic, {}, -1));
}
res.send(JSON.stringify(output));
}
};
when I get rid of the limit param from path and params subarray, the request starts working.
Do you have any idea how can I work this around or where to look in js to make a fix?
Cheers,
Maciej
Thank you for your hard work and great sharing, first of all.
I'm trying to adopt swagger(swagger-node-express) in my API service
as a consolidate API documentations and demo framework.
Every call of APIs in my API gateway must be referenced (i mean " be called")
in remote server(resource provider).
As a simple test, I tried to call one of them in Swagger API explorer.
("input_baseUrl" of index.html(swagger-ui)
then i got the following errors from the above trial,
(from Chrome debugger)
....
XMLHttpRequest cannot load http://ktas.konantech.com/ktas-api/1.0/lists/buzzcnt.json?api_key=pet. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://10.10.17.148:8001' is therefore not allowed access. (index):1
Unable to Load SwaggerUI (index):33
Can't read from server. It may not have the appropriate access-control-origin settings. (index):34
Uncaught Can't read from server. It may not have the appropriate access-control-origin settings. swagger.js:213
XMLHttpRequest cannot load http://ktas.konantech.com/ktas-api/1.0/lists/buzzcnt.json?api_key=pet. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://10.10.17.148:8001' is therefore not allowed access. (index):1
Unable to Load SwaggerUI (index):33
Can't read from server. It may not have the appropriate access-control-origin settings. (index):34
Uncaught Can't read from server. It may not have the appropriate access-control-origin settings. swagger.js:213
XMLHttpRequest cannot load http://ktas.konantech.com/ktas-api/1.0/lists/buzzcnt.json?api_key=pet. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://10.10.17.148:8001' is therefore not allowed access. (index):1
Unable to Load SwaggerUI (index):33
Can't read from server. It may not have the appropriate access-control-origin settings. (index):34
Uncaught Can't read from server. It may not have the appropriate access-control-origin settings. swagger.js:213
XMLHttpRequest cannot load http://ktas.konantech.com/ktas-api/1.0/lists/buzzcnt.json?api_key=pet. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://10.10.17.148:8001' is therefore not allowed access. (index):1
Unable to Load SwaggerUI (index):33
Can't read from server. It may not have the appropriate access-control-origin settings. (index):34
Uncaught Can't read from server. It may not have the appropriate access-control-origin settings.
....
My questions are
What exactly are the errors telling me?
I know it's related CORS problem but i couldn't figure it out clearly.
If I have the similar situation in production,
where do i have to put the codes like this ?
(i added it in main.js (Apps\petstore\main.js) )
swagger.setHeaders = function setHeaders(res) {
res.header('Access-Control-Allow-Origin', "*");
res.header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
res.header("Access-Control-Allow-Headers", "Content-Type, X-API-KEY");
res.header("Content-Type", "application/json; charset=utf-8");
};
Thanks again.
On line 74 of swagger.js (https://github.com/wordnik/swagger-node-express/blob/master/Common/node/swagger.js#L74) cors headers are overwritten, this way if you use nodejs cors (https://npmjs.org/package/cors) or express cors (https://npmjs.org/package/express-cors) the Acces-Control-Allow-xxx headers are all overwritten.
I'm working on a patch to at least fix that for my usage, but want to get it fixed for good . Any suggestions on what approach is better? I would say swagger shouldn't deal with this headers and let the cors module, that works as a middleware handle this config.
Suggestions appreciated. :-)
Has there been any thought to adding a defaultValues parameter to the paramTypes -> exports.post()? We have been playing around with dumping out the model for a route so that it has a human readable description, and sets the default value for the textarea.
The idea being that a user getting to know the a POST/PUT API path will have a JSON sample that will be ready to submit. We have it almost working, still testing. But before I push a change request I wanted to see if this was something that might be needed.
Thanks,
I'm having trouble following the https://github.com/wordnik/swagger-node-express tutorial. I'm getting the "Error: Most middleware (like json) is no longer bundled with Express and must be installed separately" error, running node v0.10.22. As per the instructions at https://github.com/senchalabs/connect#middleware I have tried installing https://github.com/expressjs/body-parser but now I am not sure how to execute the app.use(express.json() );
line. How does this work?
Thanks for your time, sorry for the noob post.
When I try accessing the petStore example using swagger-ui, I get a javascript error in swagger-service.js line 227 that this.allowableValues.create is not a function. In the debugger it appears that allowableValues is an array, not an object, at that point. If I change line 43 in petResources.js and remove the "available,pending,sold" and "available" parameters, everything works fine. Are enum properties not being sent to the UI correctly?
The "valueType" is defined twice, line 36 is a duplicate of line 30.
@fehguy Can you please bump the version and publish to NPM after the latest merges?
Thank you.
I'm using 'X-ApiKey' as my api header, but there is not a config value for this.
I can't find 'allowableValues' in the json schema spec anywhere.
http://tools.ietf.org/html/draft-zyp-json-schema-03
I can validate using enum with json-schema but enum doesn't show up in the UI.
I'd rather not specify both.
Can we bring the model definition as swagger understands it in line with json-schema?
I have a PUT call that needs to have Content-Type header set to "application/x-www-form-urlencoded" and also to include 5 parameters in the POST body:
username
password
scope
grant_type
client_id
It also has different Error responses with different JSON objects returned.
What would be a proper/working way to describe this?
(So far I am unable to find any way for how to send proper Content-Type and there is no place to describe that the body should include 5 separate parameters. There is also no place to specify that Errors will include JSON of a particular format/type)
Thanks.
You implicitly override error handling which:
You don't even document it! This is incredibly surprising behaviour.
I'd suggest replacing this with a swagger.errorHandler()
that you can plugin to express if you want to: app.use(swagger.errorHandler())
.
The (undocumented) method you offer setErrorHandler
can't accept standard express error handlers because the arguments are not in the correct order for express middleware!
swagger.setErrorHandler( express.errorHandler({showStack: true, dumpExceptions: true}))
// args incorrect, so we get `TypeError: Cannot read property 'accept' of undefined` not real error on error
Sorry if I'm annoyed, but this has wasted my time.
The "Response Class" section of the swagger-ui has been showing up blank when using the current master branch of swagger-node-express. Switching back to npm version 1.2.3 fixes the problem, so the issue seems to be somewhere between the 1.2.3 build and the current master branch.
Any thought about adding docco annotation for this project? I ask because we (NPR) are using this aggressively for our internal service API work. As we try to understand the focus on this project we have gotten into the code and found some very great, but hard to follow logic. We would be happy to take a first shot at this documentation work?
Use a fork of the repo?
Could you push to npm?
I'd like to get our codebase off the github ref.
I think v1.3.0 would be appropriate given there are some breaking changes to the API.
e.g. post() is now body()
currently we have req and res objects available for action in resources but i would like to have next object as well how can i have that like this
exports.registerAnonym = {
'spec': {
"path" : "/auth/registerAnonym",
"notes" : "Register anonym user.",
"summary" : "Register anonym user.",
"method": "POST",
"params" : [param.post("anonymUser",JSON.stringify({"anonymId":"123456","clientId":"34567"}))],
"responseClass" : "certificate",
"errorResponses" : [swe.invalid('input')],
"nickname" : "registerAnonym"
},
'action': function(req, res, next) {
console.log(next);
auth.registerAnonymUser(null,req,res,next);
}
};
Hi,
I modified the addModels function in the swagger.js file to the following. This allows the separation of models into more than one file.
It appends to, rather than replaces, the models collection in swagger.js.
// adds models to swagger
function addModels(models) {
if(!allModels['models']) {
allModels = models;
} else {
for(k in models['models']) {
allModels['models'][k] = models['models'][k];
}
}
return this;
}
This lets me organize my code a little better, and the models.js file does not get out of hand.
Not sure it is an issue really, but just thought I would put it out there as an idea.
Rich
why? Doesn't make any sense to me.
When I try accessing the petStore example using swagger-ui, I get 404 errors when clicking on the "Try it out" buttons. The problem appears to be stemming from basePath not being sent in the response to /pet.json. Swagger-ui expects the response to have a basePath attribute.
npm install swagger today tries to install 0.0.1 since that is what is registered with NPM. Could you please update your NPM listing by doing an npm publish on the 1.0.0 version so we can use it in auto deployment environments like Modulus, NodeJitsu, etc...
NPM package is behind stable master, most noticeably it lacks the req, res, next fix found in #84
Thanks
I'm trying to use a custom mode in paramPost, so that the documentation shows a different structure for POST requests than it shows for GET requests.
I have created an demo which shows this problem - https://github.com/jakul/swagger-node-express/tree/ui_model_demo
This might seem like a stupid question, but I am running a number of issues handling non UTF-8 characters. For example, 'Les Maîtres comtois' kills a request to my API. I am trying a number of approach to resolve, i.e. escape() for each form value. This means I need to unescape() on the swagger (storage) side.
Is there a recommended approach to handle this?
The User and Pet examples implement these spec values differently. Do you have examples how these should be used? or expected behavior? In the swagger.js the 'containerByModel' does not see be used. Is this a coming feature?
Adding more than one resource declarations result in an empty api list at /resources.json, {"apis":[]}.
Example :
one resource :
"path" : "/roles.{format}/{roleName}",
and the other
"path" : "/resources.{format}/{resourceName}",
I don't think swagger is properly walking the objects (recursively) to find the output objects i am not sure if this is by design or not but if you look at the example the TData object never fully gets listed as a response object unless i am doing something wrong.
"TR":
{
"id":"TR",
"required": ["seg"],
"properties":
{
"seg":
{
"items":
{
"$ref":"SR"
},
"type":"Array"
}
}
},
"SR":
{
"id":"SR",
"required": ["v","c","s","t"],
"properties":
{
"v": {"type":"integer"},
"c": {"type":"integer"},
"s": {"type":"string"},
"t":
{
"items":
{
"$ref":"TData"
},
"type":"Array"
}
}
},
"TData":
{
"id": "TData",
"required": ["abc", "efg"],
"properties":
{
"abc": {"type":"float"},
"efg": {"type":"float"}
}
}
So basicly what i am getting for output in the Response classes is below and it is missing the TData
TripResponse {
segments (Array[SegmentResponse])
}
SegmentResponse {
valid_time (integer),
creation_time (integer),
segment_id (string),
tiles (Array[TData])
}
I am having a challenge understanding the role of the basePath and the spec path. For now we are running our API on the same url and path as an endpoint (backbone.js). For this reason we have prefixed all the PATH calls with /api. But in the spec.path we are we are keeping the path simple:
exports.list = {
'spec': {
'description' : 'Get an all UCSs',
'path' : '/ucs/list',
'notes' : 'This endpoint will return all the UCS in the API.',
'summary' : 'Return all UCSs.',
'method' : 'GET',
'params' : [],
'responseClass' : 'ucs',
'errorResponses' : [ swe.invalid('id'), swe.notFound('ucs') ],
'nickname' : 'ListAllUCS'
},
'action': function (req,res) {
res.send('Example', 200);
}
}
Since we know we will be moving the entire API to its own domain and will lets the paths hang off the root, we did not want to define the path as 'path' : '/api/ucs/list'
With the upgrade to the newest swagger node package, I have had to update the addMethod call to prepend the basePath. Is this expected? Without the prepend the api will only respond using http://adomain.com/ucs/list', and will not work for http://adomain.com/api/ucs/list'
Should the bathPath be expected to apply to the spec paths?
It would be nice if the the action would allow multiple callbacks.
For example, in express you can create a route like this: app.VERB(path, [callback...], callback)
It would be nice to be able to chain the callbacks in a similar way. This would allow for using the route in the same way as express.
I'm using the latest version available in the npm as of this moment (2.0.1
)
curl -I -X OPTIONS "http://localhost:9090/api-docs"
HTTP/1.1 200 OK
X-Powered-By: Express
Allow: GET
Content-Type: text/html; charset=utf-8
Content-Length: 3
Date: Fri, 07 Feb 2014 22:55:01 GMT
Connection: keep-alive
curl -I "http://localhost:9090/api-docs"
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, PATCH, DELETE
Access-Control-Allow-Headers: Content-Type, api_key
Content-Type: application/json; charset=utf-8
Date: Fri, 07 Feb 2014 22:56:01 GMT
Connection: keep-alive
curl -I -X OPTIONS "http://petstore.swagger.wordnik.com/api/api-docs"
HTTP/1.1 204 No Content
Date: Fri, 07 Feb 2014 23:06:17 GMT
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, DELETE, PUT, PATCH, OPTIONS
Access-Control-Allow-Headers: Content-Type, api_key, Authorization
Allow: OPTIONS,GET,HEAD
Connection: close
I tried adding the setHeaders
but no luck.
The filterApiListing
method uses https://github.com/wordnik/swagger-node-express/blob/master/Common/node/swagger.js#L124 to check to see if access can be given to an particular url. However, the value of route + path
does not make sense. At this time route
is a Route
object, so adding it to the path means that nonsensical paths get passed into the validators.
$ node main.js
[object Object]/pet.*/findByTags
[object Object]/pet.*/findByStatus
[object Object]/pet.*
[object Object]/pet.*
[object Object]/pet.*
[object Object]/pet.*
[object Object]/pet.*/findByTags
[object Object]/pet.*/findByStatus
[object Object]/pet.*
[object Object]/pet.*
[object Object]/pet.*
[object Object]/pet.*
I have made a branch which allows you to see this output: https://github.com/jakul/swagger-node-express/compare/filter_api_listing_error.
What is the purpose of the Route
, and why is it added to the URL which gets passed to the validators?
Hi,
I've been hacking around with Swagger and we've come across a small issue. The API that we're trying to document is very complex and it would make it very hard to just mock every single request again.
Is it possible to instead of having the action hook, to have a clear proxy to the real API?
Thanks!
When I run the example the Response Class and Status Codes sections in the UI are not being generated for any of the operations.
Thanks for this great project.
Rich
Declaring any params as header, results in error upon startup:
[ { path: '/regions.{format}/{id}',
name: 'Authorization',
error: 'invalid param type header' } ]
Using query or path seems to be working ok...
I was not able to make it work with latest node.
When I run node Apps/petstore/main.js
I get this erros
Warning: express.createServer() is deprecated, express
applications no longer inherit from http.Server,
please use:
var express = require("express");
var app = express();
This RESTFull framework looks promising that is why I write. There some others but I like the idea of documenting and testing at the same time. I have done something the same with Zend Framework. But I believe it is not the best technology to write services.
Hi, ive noticed that swagger-node-express / Apps / petstore / models.js file starts with:
"module.exports..."
instead of
"exports.module..."
Cheers
Add more intelligent parsing for query params when allowMultiple = true.
allowMultiple in the spec isn't really handled in any way right now.
I propose adding a default split that produces an array as the query param result.
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.