OpenAPI Validator Middleware

3.2.6 · maintenance · verified Wed Apr 22

This package, `openapi-validator-middleware`, provides robust input validation for HTTP requests within Node.js frameworks such as Express, Koa, and Fastify. It leverages your existing OpenAPI (formerly Swagger) 2.0 or 3.0 definition files to automatically validate request bodies, headers, path parameters, and query parameters, using the powerful AJV library under the hood. The current stable version is 3.2.6, with the last significant update in February 2022. This suggests a maintenance-focused release cadence rather than active feature development, as over four years have passed since its last update. A key differentiator is its multi-framework support and its reliance on standardized OpenAPI definitions for validation logic, offering a consistent approach to API input schema enforcement. It was notably renamed from `express-ajv-swagger-validation` starting with version 2.0.0, which was a breaking change primarily affecting package naming and import paths for existing users.

Common errors

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to set up `openapi-validator-middleware` with an Express application. It initializes the validator with a dummy OpenAPI 3.0 specification file, applies the `validator.validate()` middleware to a route, and includes basic error handling for `InputValidationError`.

import express from 'express';
import path from 'path';
import validator from 'openapi-validator-middleware';

const app = express();
const PORT = process.env.PORT || 3000;

// Dummy OpenAPI spec for demonstration
const swaggerSpecPath = path.resolve('./swagger.yaml');
// In a real app, this would be a real file:
// fs.writeFileSync(swaggerSpecPath, `
// openapi: 3.0.0
// info:
//   title: Test API
//   version: 1.0.0
// paths:
//   /users:
//     post:
//       requestBody:
//         required: true
//         content:
//           application/json:
//             schema:
//               type: object
//               properties:
//                 name:
//                   type: string
//                 email:
//                   type: string
//                   format: email
//               required:
//                 - name
//                 - email
//       responses:
//         '200':
//           description: User created
// `);

// In a real application, ensure the OpenAPI file exists.
// For this example, we'll initialize without reading a file directly
// to focus on the middleware usage, but you'd normally point to your spec.
// For simplicity, we'll manually define a schema here.
// In a real scenario, you would initialize with a path to your spec file:
// validator.init(swaggerSpecPath, { source: 'fs' });

// Simulate initialization with an in-memory spec if no file is present
// For a real setup, provide a path to your YAML/JSON OpenAPI spec.
const inMemorySpec = {
  openapi: '3.0.0',
  info: { title: 'Test API', version: '1.0.0' },
  paths: {
    '/users': {
      post: {
        requestBody: {
          required: true,
          content: {
            'application/json': {
              schema: {
                type: 'object',
                properties: {
                  name: { type: 'string' },
                  email: { type: 'string', format: 'email' }
                },
                required: ['name', 'email']
              }
            }
          }
        },
        responses: { '200': { description: 'User created' } }
      }
    }
  }
};

// NOTE: In a real scenario, you'd call validator.init(pathToSwaggerFile)
// We simulate by directly setting the internal schema for demonstration.
// This part is for demonstration only, the library expects a file path.
console.warn('Initializing openapi-validator-middleware without a physical file for demo. Provide a path to your spec in a real app.');
// A more realistic init would be:
// try {
//   await validator.initAsync(swaggerSpecPath);
// } catch (error) {
//   console.error('Failed to initialize validator:', error.message);
//   process.exit(1);
// }

// This requires manually mocking the internal state, not directly possible via public API.
// So, for a runnable quickstart, we need an actual OpenAPI file.
// Let's create a minimal one for the example.

const fs = require('fs');
const swaggerContent = `
openapi: 3.0.0
info:
  title: Test API
  version: 1.0.0
paths:
  /users:
    post:
      summary: Create a new user
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  minLength: 3
                email:
                  type: string
                  format: email
              required:
                - name
                - email
      responses:
        '201':
          description: User created successfully
        '400':
          description: Invalid input
`;
fs.writeFileSync(swaggerSpecPath, swaggerContent);

validator.init(swaggerSpecPath);

app.use(express.json()); // Body parser middleware

app.post('/users', validator.validate(), (req, res) => {
  // If validation passes, process the request
  res.status(201).json({ message: 'User created', data: req.body });
});

// Error handling middleware for validation errors
app.use((err, req, res, next) => {
  if (err instanceof validator.InputValidationError) {
    return res.status(400).json({ 
      message: 'Validation Error', 
      errors: err.errors,
      validationContext: err.validationContext 
    });
  }
  next(err);
});

app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
  console.log(`Test with: curl -X POST -H "Content-Type: application/json" -d '{"name": "John Doe", "email": "john@example.com"}' http://localhost:${PORT}/users`);
  console.log(`Test validation failure with: curl -X POST -H "Content-Type: application/json" -d '{"name": "Jo", "email": "invalid-email"}' http://localhost:${PORT}/users`);
});

view raw JSON →