OpenAPI
access-router registers generated routes into an internal OpenAPI registry and can expose that registry as JSON and Swagger UI.
Quick Start
import express from 'express';
import acl from '@web-ts-toolkit/access-router';
const app = express();
const userRouter = acl.createRouter('User', {
basePath: '/users',
});
app.use(userRouter.routes);
app.use(
acl.createOpenApiRouter({
title: 'Example API',
version: '1.0.0',
}),
);
Default routes:
GET /openapi.jsonGET /docs
What Gets Documented
Generated documentation includes:
- model router endpoints
- data router endpoints
- root batch router endpoints
- generated path parameters, query parameters, and request bodies
- default success and error responses
- route tags and operation ids
Paths are emitted as OpenAPI-style paths such as /users/{id}.
Operation IDs
Generated operation ids follow the router naming conventions, for example:
User.listUser.createAdvancedUser.readUser.readByFilterAdvancedUser.updateAdvancedUser.members.listroot.query
Swagger UI Options
createOpenApiRouter(...) accepts:
titleversiondescriptionserversjsonPathdocsPathswaggerUiCssUrlswaggerUiBundleUrl
Example with custom paths:
app.use(
acl.createOpenApiRouter({
title: 'Internal API',
version: '2026-06-01',
jsonPath: '/spec/openapi.json',
docsPath: '/reference',
}),
);
JSON-only mode:
app.use(
acl.createOpenApiRouter({
title: 'Internal API',
version: '1.0.0',
docsPath: false,
}),
);
Custom Validation Schemas
Built-in request schemas are translated automatically.
For custom validators, attach explicit OpenAPI metadata with defineRequestSchema(...):
import { defineRequestSchema } from '@web-ts-toolkit/access-router';
const advancedCreateSchema = defineRequestSchema(
async (value) => {
return { success: true, data: value };
},
{
openapi: {
type: 'object',
properties: {
data: {
type: 'object',
additionalProperties: true,
},
},
},
},
);
Response Metadata
If a route does not override responses manually, access-router derives default responses from route metadata:
- list-like routes get list-style responses
- create routes get
201 Created - delete routes get delete-style responses
- other routes get single-resource responses
Default error responses are documented with application/problem+json payloads.
Notes
- The generated document is OpenAPI
3.1.0. - By default the OpenAPI registry is strict: registering the same
method+pathwith a non-equivalent descriptor throwsOpenApiCollisionError, and reusing anoperationIdalready bound to another route throws as well. Equivalent re-registrations marked withidempotent: true(for example the root batch routeroot.query) are still accepted as no-ops, so mounting the same routers more than once on the same runtime is safe. - To override an existing descriptor intentionally, set
allowReplace: trueon the new descriptor.allowReplacestill validates operation-ID uniqueness, so it cannot be used to steal another route'soperationId. - Low-level callers that need legacy silent-replacement behavior for migration
can construct
OpenApiRegistrydirectly with{ rejectConflicts: false, rejectDuplicateOperationIds: false }. - The inline Swagger UI script safely embeds the spec path; characters such as
</script>, quotes, ampersands, and the U+2028 / U+2029 line separators in a customjsonPathare escaped so they remain data and cannot terminate the<script>element. - The OpenAPI router documents generated routes only; your custom Express endpoints need separate registration if you want them in the same spec.