Gathering detailed insights and metrics for swagger-routes-express
Gathering detailed insights and metrics for swagger-routes-express
Gathering detailed insights and metrics for swagger-routes-express
Gathering detailed insights and metrics for swagger-routes-express
express-swagger-generator
Generates swagger doc & ui based on express existing routes.
swagger-stats
API Telemetry and APM. Trace API calls and Monitor API performance, health and usage statistics in Node.js Microservices, based on express routes and Swagger (Open API) specification
skarn-swagger
Generates swagger doc & ui based on express existing routes.
swagger-routes-express-enhanced
Connect Express route controllers to restful paths using a Swagger 2 or OpenAPI 3 definition file
npm install swagger-routes-express
Typescript
Module System
Min. Node Version
Node Version
NPM Version
87
Supply Chain
100
Quality
76.1
Maintenance
100
Vulnerability
100
License
Version 3.3.2 (upgraded dependencies)
Published on 30 Jul 2022
Version 3.3.1 (Fixed types)
Published on 19 Aug 2021
Version 3.3.0 - now with arrays of controllers
Published on 24 Jan 2021
Version 3.2.1 (Bug fix in types)
Published on 08 Jul 2020
Version 3.2.0 (TypeScript definitions)
Published on 06 Jul 2020
Version 3.1.3 (updated dependencies)
Published on 04 Jun 2020
JavaScript (100%)
Total Downloads
1,045,951
Last Day
920
Last Week
6,352
Last Month
33,333
Last Year
303,013
86 Stars
547 Commits
20 Forks
5 Watching
3 Branches
6 Contributors
Latest Version
3.3.2
Package Id
swagger-routes-express@3.3.2
Unpacked Size
41.66 kB
Size
14.05 kB
File Count
33
NPM Version
8.15.1
Node Version
18.7.0
Cumulative downloads
Total Downloads
Last day
-44.1%
920
Compared to previous day
Last week
-16.6%
6,352
Compared to previous week
Last month
2.6%
33,333
Compared to previous month
Last year
18.6%
303,013
Compared to previous year
1
Connect Express
route controllers to restful paths using a Swagger
v2 or OpenAPI
v3 definition file.
This library assumes you are using:
Add swagger-routes-express
as a dependency
:
1npm i swagger-routes-express
Assume the following API route controllers, defined in ./api/index.js
as follows:
1const { name, version, description } = require('../../package.json') 2 3const versions = (req, res) => { 4 res.json([ 5 { 6 version: 1, 7 path: '/api/v1' 8 } 9 ]) 10} 11 12const ping = (req, res) => { 13 res.json({ 14 name, 15 description, 16 version, 17 uptime: process.uptime() 18 }) 19} 20 21module.exports = { ping, versions }
Given a Swagger (v2) YAML file api.yml
along the lines of:
1swagger: '2.0' 2info: 3 description: Something about the API 4 version: '1.0.0' 5 title: 'Test API' 6basePath: '/api/v1' 7schemes: 8 - 'https' 9 - 'http' 10paths: 11 /: 12 get: 13 tags: 14 - 'root' 15 summary: 'Get API Version Information' 16 description: 'Returns a list of the available API versions' 17 operationId: 'versions' 18 produces: 19 - 'application/json' 20 responses: 21 200: 22 description: 'success' 23 schema: 24 $ref: '#/definitions/ArrayOfVersions' 25 /ping: 26 get: 27 tags: 28 - 'root' 29 summary: 'Get Server Information' 30 description: 'Returns information about the server' 31 operationId: 'ping' 32 produces: 33 - 'application/json' 34 responses: 35 200: 36 description: 'success' 37 schema: 38 $ref: '#/definitions/ServerInfo' 39definitions: 40 # see https://swagger.io/docs/specification/data-models/data-types 41 APIVersion: 42 type: 'object' 43 properties: 44 version: 45 type: 'integer' 46 format: 'int64' 47 path: 48 type: 'string' 49 ServerInfo: 50 type: 'object' 51 properties: 52 name: 53 type: 'string' 54 description: 55 type: 'string' 56 version: 57 type: 'string' 58 uptime: 59 type: 'number' 60 ArrayOfVersions: 61 type: 'array' 62 items: 63 $ref: '#/definitions/APIVersion'
1openapi: 3.0.0 2info: 3 description: Something about the API 4 version: 1.0.0 5 title: Test API 6paths: 7 /: 8 get: 9 tags: 10 - root 11 summary: Get API Version Information 12 description: Returns a list of the available API versions 13 operationId: versions 14 responses: 15 '200': 16 description: success 17 content: 18 application/json: 19 schema: 20 $ref: '#/components/schemas/ArrayOfVersions' 21 /ping: 22 get: 23 tags: 24 - root 25 summary: Get Server Information 26 description: Returns information about the server 27 operationId: ping 28 responses: 29 '200': 30 description: success 31 content: 32 application/json: 33 schema: 34 $ref: '#/components/schemas/ServerInfo' 35servers: 36 - url: /api/v1 37components: 38 schemas: 39 APIVersion: 40 type: object 41 properties: 42 version: 43 type: integer 44 format: int64 45 path: 46 type: string 47 ServerInfo: 48 type: object 49 properties: 50 name: 51 type: string 52 description: 53 type: string 54 version: 55 type: string 56 uptime: 57 type: number 58 ArrayOfVersions: 59 type: array 60 items: 61 $ref: '#/components/schemas/APIVersion'
You can connect
your Express
app or router as follows:
1const express = require('express') 2const YAML = require('yamljs') 3const { connector } = require('swagger-routes-express') 4const api = require('./api') 5 6const makeApp = () => { 7 const apiDefinition = YAML.load('api.yml') // load the api as json 8 const connect = connector(api, apiDefinition) // make the connector 9 const app = express() // make the app 10 11 // do any other app stuff, such as wire in passport, use cors etc 12 13 connect(app) // attach the routes 14 15 // add any error handlers last 16 17 return app 18}
With the result that requests to GET /
will invoke the versions
controller and a request to /ping
will invoke the ping
controller.
You can pass in an optional options
object as a third parameter to the connector
function.
1const connect = connector(api, apiDefinition, options)
If you don't pass in any options the defaults are:
1{ 2 security: {}, 3 middleware: {}, 4 onCreateRoute: undefined, 5 apiSeparator: '_', 6 notFound: : require('./routes/notFound'), 7 notImplemented: require('./routes/notImplemented'), 8 rootTag: 'root', // only used in Swagger V2 docs 9 variables: {}, // only used in OpenAPI v3 docs 10 INVALID_VERSION: require('./errors').INVALID_VERSION 11}
There are several ways to add middleware handlers, and they can be combined to provide a high degree of customisation and flexibility.
If your swagger document defines security, you can map this to your own Auth Middleware by passing in a security
option to the connector
.
For example if your path defines oAuth style security
like:
1paths: 2 /private 3 get: 4 summary: some private route 5 security: 6 - access: ['read', 'write'] 7 /admin 8 get: 9 summary: some admin route 10 security: 11 - access: ['admin']
Supply a security
option as follows
1const options = { 2 security: { 3 'read,write': readWriteAuthMiddlewareFunction, 4 admin: adminAuthMiddlewareFunction 5 } 6}
If your path defines security
, and its scopes
array is empty, you use its name in the security
option.
Given:
1paths: 2 /private 3 get: 4 summary: some private route 5 security: 6 - apiKey: []
Supply a security
option like:
1const options = { 2 security: { 3 apiKey: myAuthMiddlewareFunction 4 } 5}
Your API might wish to leverage some middleware functions but you don't want to have to specify them all in the API document itself.
Your API controller functions themselves can return arrays of controller functions.
In this case /api/v1/createThings/index.js
returns an array of controller functions with bespoke middleware controllers running in sequence, and then runs the controller in /api/v1/createThings/createThings.js
/api/v1/createThings/index.js
1const { checkIfAllowed, stripPII } = require('middleware') 2const actuallyCreateThings = require('./createThings') 3 4const createThings = [checkIfAllowed, stripPII, actuallyCreateThings]
The array of middleware and your controller will be executed in order, so it's important to put your actual controller logic last.
Both Swagger V2 and OpenAPI V3 allow you to define global security
. The global security
definition will be applied if there is no path-specific one defined.
If you've defined global security
but wish to exempt a specific path, then you can configure the path like:
1paths: 2 /my-route 3 get: 4 summary: some route that is exempt from the default security 5 security: []
An Auth Middleware Function is simply an Express Middleware function that checks to see if the user making the request is allowed to do so.
How this actually works in your server's case is going to be completely application specific, but the general idea is your app needs to be able to log users in, or accept a token from a header, or somehow otherwise stick a user id, or some roles, into req.user
or req.session.user
or something like that. There are dozens of ways to do this. I recommend using something like Passport to handle the specifics.
Your Auth Middleware then just needs to check that the user / roles you've stored corresponds with what you'd like to allow that user to do.
1async function correspondingMiddlewareFunction(req, res, next) {
2 // previously you have added a userId to req (say from an 'Authorization: Bearer token' header)
3 // how you check that the token is valid is up to your app's logic
4 if (await isValidToken(req.user.token)) return next()
5
6 // otherwise reject with an error
7 return res.status(401).json({ error: "I'm afraid you can't do that" })
8}
You can add your own path specific middleware by passing in a middleware
option:
1{ 2 middleware: { 3 myMiddleware: someMiddlewareFunction 4 } 5}
With either Swagger v2 or OpenAPI v3, add an x-middleware
option in the path specification:
1paths: 2 /special: 3 get: 4 summary: some special route 5 x-middleware: 6 - myMiddleware
The someMiddlewareFunction
will be inserted after any Auth Middleware.
You can supply an onCreateRoute
handler function with the options with signature
1const onCreateRoute = (method, descriptor) => { 2 const [path, ...handlers] = descriptor 3 console.log('created route', method, path, handlers) 4}
The method will be one of 'get', 'post', 'patch', 'put', or 'delete'.
The descriptor
is an array of:
1;[ 2 path, // a string. Swagger param formats will have been converted to express route formats. 3 security, // an auth middleware function (if needed) 4 ...middleware, // other middleware functions (if supplied) 5 controller // then finally the route controller function 6]
If your ./api
folder contains nested controllers such as:
1/api/v1/createThing.js
It's not uncommon for ./index.js
to expose this as v1_createThing
, but in swagger the operationId
might specify it as v1/createThing
.
You can supply your own apiSeparator
option in place of _
to map from /
.
In this case /api/v1/createThings.js
returns an array of controller functions with bespoke middleware controllers running in sequence. This is a shortcut for otherwise specifying middleware as outlined above.
If a route controller is defined as an operationId
in Swagger but there is no corresponding controller, a default notImplemented
controller will be inserted that simply responds with a 501
error. You can also specify your own notImplemented
controller in options
.
If no operationId
is supplied for a path then a default notFound
controller that responds with a 404
status will be inserted. You can also specify your own notFound
controller in options
.
For the root path /
we check the route's tags
. If the first tag
defined for a path is 'root'
we don't inject the api basePath
, otherwise we do. You can define your own rootTag
option to override this behaviour.
The OpenAPI V3 format allows you to define both a default servers
array, and path
specific servers
arrays. The url
fields in those arrays are parsed, ignoring any absolute URLS (as they are deemed to refer to controllers external to this API Server).
The spec allows you to include template variables in the servers
' url
field. To accommodate this you can supply a variables
option in options
. Any variables you specify will be substituted.
You can generate a summary of your Swagger v2 or OpenAPI v3 API specification in the form:
1{ 2 info: { name, version, description }, 3 paths: { [method]: ['/array', '/of', '/normalised/:paths'] } 4}
as follows:
1const YAML = require('yamljs') 2const { summarise } = require('swagger-routes-express') 3 4const apiDefinition = YAML.load('api.yml') 5const apiSummary = summarise(apiDefinition)
These docs refer to Version 3 of Swagger Routes Express which changed the way you invoke the connector
.
1const connector = require('swagger-routes-express')
1const { connector } = require('swagger-routes-express')
Branch | Status | Coverage | Audit | Notes |
---|---|---|---|---|
develop | Work in progress | |||
main | Latest stable release |
npm test
— runs the unit tests.npm run test:unit:cov
- run the unit tests with coverage.1npm run lint
The following projects use swagger-routes-express
as a starter template.
api-server-boilerplate
, andnode-express-open-api-skeleton
by Reuben Frimpong.Note: If you have a template or example of use to add to this list please just raise a PR and I'll take a look.
Please see the contributing notes.
No vulnerabilities found.
Reason
no dangerous workflow patterns detected
Reason
security policy file detected
Details
Reason
no binaries found in the repo
Reason
SAST tool detected: CodeQL
Details
Reason
license file detected
Details
Reason
4 existing vulnerabilities detected
Details
Reason
Found 0/30 approved changesets -- score normalized to 0
Reason
detected GitHub workflow tokens with excessive permissions
Details
Reason
0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0
Reason
dependency not pinned by hash detected -- score normalized to 0
Details
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Score
Last Scanned on 2024-12-16
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More