Skip to content

Commit

Permalink
Merge branch 'release/2.0.3'
Browse files Browse the repository at this point in the history
  • Loading branch information
davesag committed Apr 13, 2019
2 parents 325b8a1 + f0d74e5 commit efae252
Show file tree
Hide file tree
Showing 27 changed files with 239 additions and 113 deletions.
7 changes: 2 additions & 5 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,11 @@ jobs:

- run:
name: Javascript Linter
command:
set -e
npm run lint
command: npm run lint

- run:
name: All Unit Tests with Code Coverage
command:
npm run test:coverage
command: npm run test:coverage

- run:
name: Push any lockfile changes
Expand Down
5 changes: 2 additions & 3 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
module.exports = {
extends: ['standard', 'prettier', 'prettier/standard'],
plugins: ['prettier', 'standard', 'mocha'],
plugins: ['prettier', 'standard', 'import'],
parserOptions: {
sourceType: 'module'
},
env: {
es6: true,
node: true,
mocha: true
node: true
},
rules: {
'prettier/prettier': ['error', { singleQuote: true, semi: false }],
Expand Down
147 changes: 96 additions & 51 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# swagger-routes-express

Connect your Express route controllers to restful paths using your Swagger/OpenAPI definition file
Connect your Express route controllers to restful paths using your Swagger 2 or OpenAPI 3 definition file

[![Greenkeeper badge](https://badges.greenkeeper.io/davesag/swagger-routes-express.svg)](https://greenkeeper.io/)

Expand All @@ -12,6 +12,8 @@ Connect your Express route controllers to restful paths using your Swagger/OpenA
| `develop` | [![CircleCI](https://circleci.com/gh/davesag/swagger-routes-express/tree/develop.svg?style=svg)](https://circleci.com/gh/davesag/swagger-routes-express/tree/develop) | [![codecov](https://codecov.io/gh/davesag/swagger-routes-express/branch/develop/graph/badge.svg)](https://codecov.io/gh/davesag/swagger-routes-express) | Work in progress |
| `master` | [![CircleCI](https://circleci.com/gh/davesag/swagger-routes-express/tree/master.svg?style=svg)](https://circleci.com/gh/davesag/swagger-routes-express/tree/master) | [![codecov](https://codecov.io/gh/davesag/swagger-routes-express/branch/master/graph/badge.svg)](https://codecov.io/gh/davesag/swagger-routes-express) | Latest stable release |

[![NPM](https://nodei.co/npm/swagger-routes-express.png)](https://nodei.co/npm/swagger-routes-express/)

## Prerequisites

This library assumes:
Expand All @@ -23,7 +25,7 @@ This library assumes:

Add `swagger-routes-express` as a `dependency`:

```
```sh
npm i swagger-routes-express
```

Expand All @@ -33,7 +35,7 @@ npm i swagger-routes-express

Assume the following API route controllers, defined in `./api/index.js` as follows:

```
```js
const { name, version, description } = require('../../package.json')

const versions = (req, res) => {
Expand Down Expand Up @@ -61,75 +63,75 @@ module.exports = { ping, versions }

Given a Swagger (v2) YAML file `my-api.yml` along the lines of:

```
swagger: "2.0"
```yml
swagger: '2.0'
info:
description: Something about the API
version: "1.0.0"
title: "Test API"
basePath: "/api/v1"
version: '1.0.0'
title: 'Test API'
basePath: '/api/v1'
schemes:
- "https"
- "http"
- 'https'
- 'http'
paths:
/:
get:
tags:
- "root"
summary: "Get API Version Information"
description: "Returns a list of the available API versions"
operationId: "versions"
- 'root'
summary: 'Get API Version Information'
description: 'Returns a list of the available API versions'
operationId: 'versions'
produces:
- "application/json"
- 'application/json'
responses:
200:
description: "success"
description: 'success'
schema:
$ref: "#/definitions/ArrayOfVersions"
$ref: '#/definitions/ArrayOfVersions'
/ping:
get:
tags:
- "root"
summary: "Get Server Information"
description: "Returns information about the server"
operationId: "ping"
- 'root'
summary: 'Get Server Information'
description: 'Returns information about the server'
operationId: 'ping'
produces:
- "application/json"
- 'application/json'
responses:
200:
description: "success"
description: 'success'
schema:
$ref: "#/definitions/ServerInfo"
$ref: '#/definitions/ServerInfo'
definitions:
# see https://swagger.io/docs/specification/data-models/data-types
APIVersion:
type: "object"
type: 'object'
properties:
version:
type: "integer"
format: "int64"
type: 'integer'
format: 'int64'
path:
type: "string"
type: 'string'
ServerInfo:
type: "object"
type: 'object'
properties:
name:
type: "string"
type: 'string'
description:
type: "string"
type: 'string'
version:
type: "string"
type: 'string'
uptime:
type: "number"
type: 'number'
ArrayOfVersions:
type: "array"
type: 'array'
items:
$ref: "#/definitions/APIVersion"
$ref: '#/definitions/APIVersion'
```
### Or as an OpenAPI Version 3 example
### OpenAPI Version 3 example
```
```yml
openapi: 3.0.0
info:
description: Something about the API
Expand Down Expand Up @@ -197,7 +199,7 @@ components:
You could set up your server as follows:
```
```js
const express = require('express')
const SwaggerParser = require('swagger-parser')
const swaggerRoutes = require('swagger-routes-express')
Expand All @@ -220,20 +222,63 @@ const makeApp = async () => {

With the result that requests to `GET /` will invoke the `versions` controller and a request to `/ping` will invoke the `ping` controller.

### Adding security handlers
### Adding security middleware handlers

You can pass in a range of options, so if your swagger document defines security scopes you can pass in via a `security` option:

For example if your path has a `security` block like

```yml
paths:
/private
get:
summary: some private route
security:
- access: ['read', 'write']
/admin
get:
summary: some admin route
security:
- access: ['admin']
```
Supply a `security` option as follows

```js
const options = {
security: {
'read-write': readWriteAuthMiddlewareFunction,
admin: adminAuthMiddlewareFunction
}
}
```

You can pass in a range of options, so if your swagger document defines security scopes you can pass in the following `scopes` option:
If your paths supply a `security` block but its `scopes` array is empty you can just use its name instead in the `security` option.

```yml
paths:
/private
get:
summary: some private route
security:
- apiKey: []
```

supply a `security` option like

```js
const options = {
scopes: {
'my-scope': correspondingMiddlewareFunction,
'my-other-scope': otherAuthMiddleware,
'admin': adminAuthMiddleware
security: {
apiKey: myAuthMiddlewareFunction
}
}
```

#### Notes

- Only the **first** security option is used.
- The previous version of `swagger-routes-express` used a `scopes` option but this didn't make sense for security without scopes. To preserve backwards compatibility the `scopes` option is still permitted but you'll get a deprecation warning.

#### What's an Auth Middleware function?

An Auth Middleware Function is simply an [Express Middleware function](https://expressjs.com/en/guide/using-middleware.html) that checks to see if the user making the request is allowed to do so.
Expand All @@ -242,7 +287,7 @@ How this actually works in your server's case is going to be completely applicat

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.

```
```js
async function correspondingMiddlewareFunction(req, res, next) {
// previously you have added a userId to req (say from an 'Authorization: Bearer token' header)
// how you check that the token is valid is up to your app's logic
Expand All @@ -263,7 +308,7 @@ OpenAPI V3 allows you to define a global `security` definition as well as path s

You can supply an `onCreateRoute` handler function with the options with signature

```
```js
const onCreateRoute = (method, descriptor) => {
const [path, ...handlers] = descriptor
console.log('created route', method, path, handlers)
Expand All @@ -274,8 +319,8 @@ The method will be one of `get`, `put`, `post`, `delete`, etc.

The descriptor is an array of

```
[
```js
;[
path, // a string. Swagger param formats will have been converted to express route formats.
security, // a middleware function (if needed)
controller // a route controller function
Expand Down Expand Up @@ -316,14 +361,14 @@ The spec allows you to include template variables in the `servers`' `url` field.
If you don't pass in any options the defaults are:
```
```js
{
apiSeparator: '_',
notFound: : require('./routes/notFound'),
notImplemented: require('./routes/notImplemented'),
onCreateRoute: undefined,
rootTag: 'root', // unused in OpenAPI v3 docs
scopes: {},
security: {},
variables: {}, // unused in Swagger V2 docs
INVALID_VERSION: require('./errors').INVALID_VERSION
}
Expand All @@ -342,7 +387,7 @@ If you don't pass in any options the defaults are:

### Lint it

```
```sh
npm run lint
```

Expand Down
Loading

0 comments on commit efae252

Please sign in to comment.