Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
cdimascio authored Dec 4, 2019
1 parent c00a10a commit 7ed69fc
Showing 1 changed file with 142 additions and 109 deletions.
251 changes: 142 additions & 109 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,16 @@ _**Note:** Ensure express is configured with all relevant body parsers. Body par

## Usage (options)

See examples using [promises](#promise) and [callbacks](#callback). Or use it [synchronously](#synchronous)

See [Advanced Usage](#Advanced-Usage) options to:

- inline api specs as JSON.
- configure request/response validation options
- tweak the file upload configuration.
- customize authentication with security `handlers`.
- customize authentication with security validation `handlers`.
- use OpenAPI 3.0.x 3rd party and custom formats.
- tweak the file upload configuration.
- ignore routes
- and more...

## [Example Express API Server](https://github.com/cdimascio/express-openapi-validator/tree/master/example)
Expand Down Expand Up @@ -109,7 +112,6 @@ app.use('/spec', express.static(spec));
new OpenApiValidator({
apiSpec: './example.yaml',
validateResponses: true, // <-- to validate responses
// validateSecurity: { handlers: { ... }} // <-- to use custom security handlers
// unknownFormats: ['my-format'] // <-- to provide custom formats
})
.install(app)
Expand Down Expand Up @@ -310,85 +312,6 @@ Errors in response validation return `500`, not of `400`

### _...and much more. Try it out!_

## Other Usage Options

In addition to async/await, express-openapi-validator may be used with promises, callbacks, or synchronously.

_**Note:** Ensure express is configured with all relevant body parsers. Body parser middleware functions must be specified prior to any validated routes. See an [example](#example-express-api-server)_.

#### Promise

```javascript
new OpenApiValidator({
apiSpec: './test/resources/openapi.yaml',
validateRequests: true, // (default)
validateResponses: true, // false by default
})
.install(app)
.then(app => {
// define your routes

// register an error handler
app.use((err, req, res, next) => {
res.status(err.status || 500).json({
message: err.message,
errors: err.errors,
});
});
});
```

#### Callback

```javascript
new OpenApiValidator({
apiSpec: './test/resources/openapi.yaml',
validateRequests: true, // (default)
validateResponses: true, // false by default
}).install(app, (err, _) => {
// define your routes

// register an error handler
app.use((err, req, res, next) => {
res.status(err.status || 500).json({
message: err.message,
errors: err.errors,
});
});
});
```

#### Synchronous

_Note syncrhonous mode makes use of the [`deasync`](https://github.com/abbr/deasync) module. Some users have experienced issues using deasync with some versions of node_

**Q:** What does it mean to use the validator 'synchronously'?

**A:** The validator's initial parse and `$ref` resolution of the OpenAPI 3 spec are executed synchronously. Use `installSync(app)` instead of `install(app)` to setup the validator in a blocking manner.

**Install**

1. Install the openapi validator

```javascript
new OpenApiValidator({
apiSpec: './test/resources/openapi.yaml',
validateRequests: true, // (default)
validateResponses: true, // false by default
}).installSync(app);
```

2. Register an error handler

```javascript
app.use((err, req, res, next) => {
// format error
res.status(err.status || 500).json({
message: err.message,
errors: err.errors,
});
});
```

## Advanced Usage

Expand All @@ -403,16 +326,16 @@ new OpenApiValidator(options).install({
apiSpec: './openapi.yaml',
validateRequests: true,
validateResponses: true,
ignorePaths: /.*\/pets$/
unknownFormats: ['phone-number', 'uuid'],
multerOpts: { ... },
validateSecurity: {
handlers: {
ApiKeyAuth: (req, scopes, schema) => {
throw { status: 401, message: 'sorry' }
}
}
}
ignorePaths: /.*\/pets$/
unknownFormats: ['phone-number', 'uuid'],
multerOpts: { ... },
});
```

Expand Down Expand Up @@ -480,6 +403,47 @@ Determines whether the validator should validate responses. Also accepts respons
}
```

### ▪️ validateSecurity (optional)

Determines whether the validator should validate securities e.g. apikey, basic, oauth2, openid, etc

- `true` (**default**) - validate security
- `false` - do not validate security
- `{ ... }` - validate security with options. [Full security option details](#security_handlers)

**handlers:**

Method signature:

```typescript
{
validateSecurity: {
handlers: {
[securityKey]: function(
req: Express.Request,
scopes: string[],
schema: SecuritySchemeObject
): void,
}
}
}
```
[SecuritySchemeObject](https://github.com/cdimascio/express-openapi-validator/blob/master/src/framework/types.ts#L269)
For example:
```javascript
validateSecurity: {
handlers: {
ApiKeyAuth: function(req, scopes, schema) {
console.log('apikey handler throws custom error', scopes, schema);
throw Error('my message');
},
}
}
```
### ▪️ ignorePaths (optional)
Defines a regular expression that determines whether a path(s) should be ignored. Any path which matches the regular expression will not be validated.
Expand Down Expand Up @@ -516,18 +480,19 @@ Determines whether the validator should coerce value types to match the type def
- `false` - no type coercion.
- `"array"` - in addition to coercions between scalar types, coerce scalar data to an array with one element and vice versa (as required by the schema).
### ▪️ validateSecurity (optional)
## Security handlers
Determines whether the validator should validate securities e.g. apikey, basic, oauth2, openid, etc
> **Note:** security `handlers` are an optional component. security `handlers` provide a convenience, whereby the request, declared scopes, and the security schema itself are provided as parameters to each security `handlers` callback that you define. The code you write in each callback can then perform authentication and authorization checks. **_Note that the same can be achieved using standard Express middleware_. The difference** is that security `handlers` provide you the OpenAPI schema data described in your specification\_. Ulimately, this means, you don't have to duplicate that information in your code.
> All in all, security `handlers` are purely optional and are provided as a convenience.
- `true` (**default**) - validate security
- `false` - do not validate security
- `{ ... }` - validate security with options
Security handlers specify a set of custom security handlers to be used to validate security i.e. authentication and authorization. If a security `handlers` object is specified, a handler must be defined for **_all_** securities. If `securityHandlers are **_not_** specified, a default handler is always used. The default handler will validate against the OpenAPI spec, then call the next middleware.

**handlers:**
If `securityHandlers` are specified, the validator will validate against the OpenAPI spec, then call the security handler providing it the Express request, the security scopes, and the security schema object.

- security `handlers` is an object that maps security keys to security handler functions. Each security key must correspond to `securityScheme` name.
The `validateSecurity.handlers` object signature is as follows:

Method signature:

```typescript
{
validateSecurity: {
Expand All @@ -544,7 +509,7 @@ Determines whether the validator should validate securities e.g. apikey, basic,

[SecuritySchemeObject](https://github.com/cdimascio/express-openapi-validator/blob/master/src/framework/types.ts#L269)

For example:
**For example:**

```javascript
validateSecurity: {
Expand All @@ -555,21 +520,10 @@ Determines whether the validator should validate securities e.g. apikey, basic,
},
}
}
```
> **Note:** security `handlers` are an optional component. security `handlers` provide a convenience, whereby the request, declared scopes, and the security schema itself are provided as parameters to each security `handlers` callback that you define. The code you write in each callback can then perform authentication and authorization checks. **_Note that the same can be achieved using standard Express middleware_. The difference** is that security `handlers` provide you the OpenAPI schema data described in your specification\_. Ulimately, this means, you don't have to duplicate that information in your code.
> All in all, security `handlers` are purely optional and are provided as a convenience.
Security handlers specify a set of custom security handlers to be used to validate security i.e. authentication and authorization. If a security `handlers` object is specified, a handler must be defined for **_all_** securities. If `securityHandlers are **_not_** specified, a default handler is always used. The default handler will validate against the OpenAPI spec, then call the next middleware.

If `securityHandlers` are specified, the validator will validate against the OpenAPI spec, then call the security handler providing it the Express request, the security scopes, and the security schema object.

- security `handlers` is an object that maps security keys to security handler functions. Each security key must correspond to `securityScheme` name.
The `validateSecurity.handlers` object signature is as follows:

```


The _express-openapi-validator_ performs a basic validation pass prior to delegating to security handlers. If basic validation passes, security handler function(s) are invoked.
The _express-openapi-validator_ performs a basic validation pass prior to delegating to security handlers. If basic validation passes, security handler function(s) are invoked.

In order to signal an auth failure, the security handler function **must** either:

Expand Down Expand Up @@ -635,9 +589,88 @@ Determines whether the validator should validate securities e.g. apikey, basic,
name: X-API-Key
```
See [OpenAPI 3](https://swagger.io/docs/specification/authentication/) authentication for `securityScheme` and `security` documentation
See [OpenAPI 3](https://swagger.io/docs/specification/authentication/) authentication for `securityScheme` and `security` documentation
See [examples](https://github.com/cdimascio/express-openapi-validator/blob/security/test/security.spec.ts#L17) from unit tests
## Other Usage Options
In addition to async/await, express-openapi-validator may be used with promises, callbacks, or synchronously.
_**Note:** Ensure express is configured with all relevant body parsers. Body parser middleware functions must be specified prior to any validated routes. See an [example](#example-express-api-server)_.
#### Promise
```javascript
new OpenApiValidator({
apiSpec: './test/resources/openapi.yaml',
validateRequests: true, // (default)
validateResponses: true, // false by default
})
.install(app)
.then(app => {
// define your routes

// register an error handler
app.use((err, req, res, next) => {
res.status(err.status || 500).json({
message: err.message,
errors: err.errors,
});
});
});
```
#### Callback
```javascript
new OpenApiValidator({
apiSpec: './test/resources/openapi.yaml',
validateRequests: true, // (default)
validateResponses: true, // false by default
}).install(app, (err, _) => {
// define your routes

// register an error handler
app.use((err, req, res, next) => {
res.status(err.status || 500).json({
message: err.message,
errors: err.errors,
});
});
});
```
#### Synchronous
_Note syncrhonous mode makes use of the [`deasync`](https://github.com/abbr/deasync) module. Some users have experienced issues using deasync with some versions of node_
**Q:** What does it mean to use the validator 'synchronously'?
**A:** The validator's initial parse and `$ref` resolution of the OpenAPI 3 spec are executed synchronously. Use `installSync(app)` instead of `install(app)` to setup the validator in a blocking manner.
**Install**
1. Install the openapi validator
```javascript
new OpenApiValidator({
apiSpec: './test/resources/openapi.yaml',
validateRequests: true, // (default)
validateResponses: true, // false by default
}).installSync(app);
```
See [examples](https://github.com/cdimascio/express-openapi-validator/blob/security/test/security.spec.ts#L17) from unit tests
2. Register an error handler
```javascript
app.use((err, req, res, next) => {
// format error
res.status(err.status || 500).json({
message: err.message,
errors: err.errors,
});
});
```
## The Base URL
Expand Down

0 comments on commit 7ed69fc

Please sign in to comment.