Install @wesleytodd/openapi via npm
mainInstall the middleware using npm to begin generating and validating OpenAPI documentation in your Express application.
$ npm install --save @wesleytodd/openapirepository·main·Indexed 40 days ago
https://github.com/wesleytodd/express-openapiMiddleware for Express applications that automates the generation and validation of OpenAPI/Swagger documentation. Version 1.1.0 allows developers to define API schemas directly within route handlers using .path() and .validPath(), manage components via .component(), and serve an interactive Swagger UI.
Install the middleware using npm to begin generating and validating OpenAPI documentation in your Express application.
$ npm install --save @wesleytodd/openapiThe ExpressOpenApi function (exported as the default) initializes the OpenAPI middleware. It can be called with several argument combinations to configure the route prefix, the OpenAPI document, and additional options.
Argument patterns:
oapi(): Uses default prefix (/openapi) and a minimum viable document.oapi('/path'): Sets a custom route prefix.oapi('/path', doc): Sets a custom prefix and provides an initial OpenAPI document.oapi('/path', doc, opts): Sets prefix, document, and configuration options.oapi(doc): Uses default prefix and provides a document.oapi(doc, opts): Uses default prefix, provides a document, and options.Options:
basePath: Used during document generation.htmlui: If set to 'swagger-ui', the middleware will automatically set up Swagger UI routes at the routePrefix.const ExpressOpenApi = require('express-openapi');
// Example: Initialize with a custom prefix and options
const oapi = ExpressOpenApi('/api/docs', myDoc, { basePath: '/api/v1', htmlui: 'swagger-ui' });
// Use in Express
app.use(oapi);Use the openapi() function to create an instance of the documentation middleware. This instance is a middleware function that you mount to your Express app (e.g., app.use(oapi)), and it is decorated with helper methods for defining paths, components, and serving UI.
const openapi = require('@wesleytodd/openapi')
const app = require('express')()
const oapi = openapi({
openapi: '3.0.0',
info: {
title: 'Express Application',
description: 'Generated docs from an Express api',
version: '1.0.0',
}
})
app.use(oapi)The .path([definition]) method returns a middleware function that registers an OperationObject definition into your OpenAPI document. This is used to add metadata (like responses and schemas) to a specific route without performing request validation.
app.get('/:foo', oapi.path({
description: 'Get a foo',
responses: {
200: {
content: {
'application/json': {
schema: {
type: 'object',
properties: {
foo: { type: 'string' }
}
}
}
}
}
}
}), (req, res) => {
res.json({
foo: req.params.foo
})
})Use .component(type, [name, definition]) to add items to the components section of your OpenAPI document.
Variadic Behavior:
oapi.component(type, name, definition): Creates a new component.oapi.component(type, name): Returns a Reference Object ($ref) pointing to that component.oapi.component(type): Returns the full components JSON object.Specialized Helpers:
Instead of calling .component() with a type string, you can use these bound helpers:
.schema(name, definition).response(name, definition).parameters(name, definition).examples(name, definition).requestBodies(name, definition).headers(name, definition).securitySchemes(name, definition).links(name, definition).callbacks(name, definition)// Create a component
oapi.component('examples', 'FooExample', {
summary: 'An example of foo',
value: 'bar'
})
// Get a reference to a component
const ref = oapi.component('examples', 'FooExample');
// returns { '$ref': '#/components/examples/FooExample' }The .validPath([definition [, pathOpts]]) method registers a path in the OpenAPI document AND ensures incoming requests are valid against the provided schema.
If validation fails, it calls next(err) with an error created via http-errors. The error object is augmented with:
err.validationErrors: The error format from ajv.err.validationSchema: The schema that failed.To support custom validation (like ajv-keywords), pass { keywords: [...] } as the second argument (pathOpts).
app.get('/:foo', oapi.validPath({
description: 'Get a foo',
responses: {
200: {
content: {
'application/json': {
schema: {
type: 'object',
properties: {
foo: { type: 'string' }
}
}
}
}
}
}
}), (err, req, res, next) => {
if (err) {
res.status(err.status).json({
error: err.message,
validation: err.validationErrors,
schema: err.validationSchema
})
return
}
res.json({ foo: req.params.foo })
})The .swaggerui() method returns middleware to serve an interactive Swagger UI for exploring your OpenAPI document. This is not enabled by default unless you use the htmlui: true option in the main openapi() config or call this method explicitly.
You can pass an optional configuration object to swaggerui() to configure Swagger or Redoc parameters.
// Serve Swagger UI at the /swaggerui path
app.use('/swaggerui', oapi.swaggerui())When calling openapi([route [, document[, options]]]), you can provide an options object to customize behavior:
options.coerce: (Boolean) Controls data type coercion. By default, a copy of req is passed to prevent modifying the original request. If set to true, the original req is used, allowing AJV to convert types (e.g., string to number) directly on the request object.options.htmlui: (Boolean) Enables serving the swagger-ui HTML interface.options.basePath: (String) When set, this value is stripped from the start of every path in the generated document.To provide a visual interface for exploring your OpenAPI documentation, use the swaggerui() method. This returns a middleware that serves the Swagger UI assets.
If you initialized the middleware with { htmlui: 'swagger-ui' } in the options, the routes are automatically configured. Otherwise, you can call it manually.
const oapi = ExpressOpenApi('/openapi', myDoc);
// Manually adding Swagger UI
app.use(oapi.swaggerui({ /* swagger-ui options */ }));The middleware provides helper methods to define and register OpenAPI components (like schemas, parameters, or security schemes) directly into the generated document.
Methods:
middleware.component(type, name, description): The base method for defining any component type.middleware.schema(name, description): Shortcut for component('schemas', ...).middleware.response(name, description): Shortcut for component('responses', ...).middleware.parameters(name, description): Shortcut for component('parameters', ...).middleware.examples(name, description): Shortcut for component('examples', ...).middleware.requestBodies(name, description): Shortcut for component('requestBodies', ...).middleware.headers(name, description): Shortcut for component('headers', ...).middleware.securitySchemes(name, description): Shortcut for component('securitySchemes', ...).middleware.links(name, description): Shortcut for component('links', ...).middleware.callbacks(name, description): Shortcut for component('callbacks', ...).Behavior:
name and description, it defines a new component.name, it returns a JSON Reference ($ref) to the existing component.const oapi = ExpressOpenApi('/openapi', myDoc);
// Define a new schema
oapi.schema('User', { type: 'object', properties: { id: { type: 'string' } } });
// Get a reference to the schema
const userRef = oapi.schema('User'); // returns { $ref: '#/components/schemas/User' }The middleware provides two ways to attach OpenAPI definitions to specific routes for documentation and validation.
middleware.path(schema)Registers a schema for a specific path. This is primarily used for documentation purposes to ensure the path is included in the generated OpenAPI document.
middleware.validPath(schema, pathOpts)Returns a middleware function that validates incoming requests against the provided OpenAPI schema. It uses the internal validator to check the request against the schema.
Note: Both methods return a middleware function that you must then use in your Express route definitions.
const oapi = ExpressOpenApi('/openapi', myDoc);
const userSchema = { type: 'object', properties: { id: { type: 'string' } } };
// For documentation only
app.get('/user/:id', oapi.path(userSchema), (req, res) => {
res.send('User info');
});
// For documentation AND request validation
app.post('/user', oapi.validPath(userSchema), (req, res) => {
res.send('User created');
});The middleware automatically exposes several endpoints based on the routePrefix provided during initialization:
GET {routePrefix}.json: Returns the full OpenAPI document as JSON.GET {routePrefix}.yaml or {routePrefix}.yml: Returns the full OpenAPI document as YAML.GET {routePrefix}/components/{type}/{name}.json: Returns a specific component definition (e.g., a single schema) as JSON.GET {routePrefix}/validate: Returns a validation report of the current OpenAPI document using swagger-parser.