JSPM

express-openapi-validator

2.2.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 382134
  • Score
    100M100P100Q184432F
  • License MIT

Automatically validate API requests using an OpenAPI 3 and Express.

Package Exports

  • express-openapi-validator

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (express-openapi-validator) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

express-openapi-validator

Coverage Status All Contributors

An OpenApi validator for ExpressJS that automatically validates API requests using an OpenAPI 3 specification.

express-openapi-validator is unopinionated and does not impose any coding convention or project structure. Simply, install the validator onto your express app, point it to your OpenAPI 3 specification, then define and implement routes the way you prefer. See an example.

GitHub stars Twitter URL

Install

npm i express-openapi-validator

Usage

Install the openapi validator

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

Note: response validation is currently a beta feature

Then, register an error handler to customize errors

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

Alternatively...

The apiSpec option may be specified as the spec object itself, rather than a path e.g.

const apiSpec = {
  openapi: "3.0.1",
  info: {...},
  servers: [...],
  paths: {...},
  components: {
    responses: {...},
    schemas: {...}
  }
}

new OpenApiValidator({ apiSpec }).install(app);

Options

new OpenApiValidator(options).install(app);

apiSpec: a string value specifying the path to the OpenAPI 3.0.x spec or a JSON object representing an OpenAPI spec.

validateRequests: enable response validation.

  • true - (default) validate requests
  • false - do not validate requests

validateResponses: enable response validation.

  • true - validate responses
  • false - (default) do not validate responses

coerceTypes: change data type of data to match type keyword. See the example in Coercing data types and coercion rules. Option values:

  • true - (default) coerce scalar data types.
  • 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).

multerOpts: the multer opts to passthrough to multer

Example Express API Server

Try the complete example below: (it includes file upload as well!)

const express = require('express');
const path = require('path');
const cookieParser = require('cookie-parser');
const bodyParser = require('body-parser');
const logger = require('morgan');
const http = require('http');
const app = express();

// 1. Import the express-openapi-validator library
const OpenApiValidator = require('express-openapi-validator').OpenApiValidator;

app.use(bodyParser.json());
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

// 2. (optionally) Serve the OpenAPI spec
app.use('/spec', express.static(spec));

// 3. Install the OpenApiValidator onto your express app
new OpenApiValidator({
  apiSpec: './openapi.yaml',
}).install(app);

// 4. Define routes using Express
app.get('/v1/pets', function(req, res, next) {
  res.json([{ id: 1, name: 'max' }, { id: 2, name: 'mini' }]);
});

app.post('/v1/pets', function(req, res, next) {
  res.json({ name: 'sparky' });
});

app.get('/v1/pets/:id', function(req, res, next) {
  res.json({ id: req.params.id, name: 'sparky' });
});

// 4. Define route(s) to upload file(s)
app.post('/v1/pets/:id/photos', function(req, res, next) {
  // files are found in req.files
  // non-file multipart params can be found as such: req.body['my-param']

  res.json({
    files_metadata: req.files.map(f => ({
      originalname: f.originalname,
      encoding: f.encoding,
      mimetype: f.mimetype,
      // Buffer of file conents
      buffer: f.buffer,
    })),
  });
});

// 5. Create an Express error handler
app.use((err, req, res, next) => {
  // 6. Customize errors
  res.status(err.status).json({
    message: err.message,
    errors: err.errors,
  });
});

Example Express API Server (clone it)

A fully working example lives here

Example validation responses

Validate a query parameter with a value constraint

/pets/:id should be of type integer, express-openapi-validator returns:

curl -s http://localhost:3000/v1/pets/as |jq
{
  "errors": [
    {
      "path": ".params.id",
      "message": "should be integer",
      "errorCode": "type.openapi.validation"
    }
  ]
}

Validate a query parameter with a range constraint

/pets?limit=? should be of type integer with a value greater than 5. It should also require an additional query paramter, test, express-openapi-validator returns:

curl -s http://localhost:3000/v1/pets?limit=1 |jq
{
  "errors": [
    {
      "path": ".query.limit",
      "message": "should be >= 5",
      "errorCode": "minimum.openapi.validation"
    },
    {
      "path": ".query.test",
      "message": "should have required property 'test'",
      "errorCode": "required.openapi.validation"
    }
  ]
}

Validate the query parameter's value type

POST /pets is defined to only accept media type application/json, express-openapi-validator returns:

curl -s --request POST \
  --url http://localhost:3000/v1/pets \
  --header 'content-type: application/xml' \
  --data '{
        "name": "test"
}' |jq
{
  "errors": [
    {
      "path": "/v1/pets",
      "message": "unsupported media type application/xml"
    }
  ]
}

Validate a POST body to ensure required parameters are present

POST /pets request body is required to contain the name properly, express-openapi-validator returns:

curl -s --request POST \
  --url http://localhost:3000/v1/pets \
  --header 'content-type: application/json' \
  --data '{}' |jq
{
  "errors": [
    {
      "path": ".query.name",
      "message": "should have required property 'name'",
      "errorCode": "required.openapi.validation"
    }
  ]
}

Validate a POST multipart/form-data request

curl -s -XPOST http://localhost:3000/v1/pets/10/photos -F fileZZ=@app.js | jq
{
  "errors": [
    {
      "path": "file",
      "message": "should have required property 'file'",
      "errorCode": "required.openapi.validation"
    }
  ]
}

...and much more. Try it out!

Contributors ✨

Thanks goes to these wonderful people (emoji key):

Carmine DiMascio
Carmine DiMascio

💻 ⚠️ 🚇
Sheldhur Mornor
Sheldhur Mornor

💻 ⚠️
Andrey Trebler
Andrey Trebler

💻 ⚠️

This project follows the all-contributors specification. Contributions of any kind welcome!

License

MIT