A lightweight, type-safe Express.js integration library for OpenAPI specifications. This package enables you to build type-safe REST APIs with full request/response validation using OpenAPI schemas.
See examples/ for a complete working example.
The first step is to generate TypeScript type definitions from your OpenAPI specification using openapi-typescript.
npm install --save-dev openapi-typescript
Add this script to your package.json:
{
"scripts": {
"generate:types": "openapi-typescript path/to/your/openapi.yaml --output path/to/generated/types.ts"
}
}
Then run it to generate the types:
npm run generate:types
It's also recommended to add it to your compile/build script to ensure types are always up to date.
{
"scripts": {
"build": "npm run generate:types && tsc"
}
}
This command generates a types.ts file with path types that look like:
export interface paths {
'/users': {
get: {
responses: {
'200': {
content: {
'application/json': {
id: string
name: string
}
}
}
}
}
}
// ... more paths
}
npm install ts-openapi-express
yarn add ts-openapi-express
pnpm add ts-openapi-express
import { openapiExpress } from 'ts-openapi-express'
import { paths } from './generated/types' // Generated from step 1
const app = openapiExpress<paths>({
specPath: './openapi.yaml',
routes: {
'/users': {
get: {
handler: async (req) => ({
200: {
headers: {},
body: [
{ id: '1', name: 'John' },
{ id: '2', name: 'Jane' },
],
},
}),
},
post: {
handler: async (req) => ({
201: {
headers: { 'content-type': 'application/json' },
body: { id: '3', name: req.body.name },
},
}),
},
},
'/users/{id}': {
get: {
handler: async (req) => ({
200: {
headers: {},
body: { id: req.params.id, name: 'John' },
},
}),
},
},
},
})
app.listen(3000, () => {
console.log('API running on http://localhost:3000')
console.log('OpenAPI spec available at http://localhost:3000/openapi.json')
})
See the examples/ directory for complete working examples, including a simple blog API.
interface OpenapiExpressOptions<Spec> {
/**
* Path to your OpenAPI specification file (YAML or JSON)
*/
specPath: string
/**
* Route handlers object mapping paths to HTTP method handlers
*/
routes: Routes<Spec>
/**
* Optional Express middleware to use
*/
middleware?: ExpressMiddleware[]
/**
* Enable request validation against OpenAPI spec (default: true)
*/
validateRequest?: boolean
/**
* Enable response validation against OpenAPI spec (default: true)
*/
validateResponse?: boolean
/**
* Automatically parse JSON request bodies (default: true)
*/
decodeJsonBody?: boolean
/**
* Provide an existing Express app instance (optional)
*/
app?: Application
/**
* Disable the 'X-Powered-By' header (default: true)
*/
disableXPoweredBy?: boolean
}
Route handlers receive type-safe request objects with:
req.params: Path parameters (fully typed)req.query: Query parameters (fully typed)req.body: Request body (fully typed)req.headers: HTTP headersHandlers must return a response object with a single status code:
{
200: {
headers: { 'content-type': 'application/json' },
body: { /* response data */ }
}
}
Or, if no body is required:
{
204: {
headers: {}
}
}
Streaming responses are supported by passing a Node.js Readable:
{
200: {
headers: { 'content-type': 'text/csv' },
body: fs.createReadStream('data.csv')
}
}
This repository includes a comprehensive test suite that demonstrates usage. To run it:
# This will:
# 1. Generate types from the OpenAPI spec
# 2. Run the test suite with validation
npm test
The test file at packages/ts-openapi-express/test/unit/openapi.test.ts shows:
If you modify the test OpenAPI spec, regenerate the types:
npm run test:compile:spec
The library works in three main steps:
MIT