nestrs-openapi discovers all routes registered through #[routes] and impl_routes!, builds an OpenAPI 3.1 document, and serves it at GET /openapi.json. A Swagger UI page is available at GET /docs. You enable the whole thing with a single method call on NestApplication — no separate server, no build step.
What is generated automatically
Step-by-step setup
1
Enable the feature
Add the
openapi feature to your nestrs dependency, or add nestrs-openapi directly if you need the standalone router.2
Call enable_openapi() before listen
Chain Your API is now self-documenting. Open
enable_openapi() on the NestApplication returned by NestFactory::create. This registers GET /openapi.json and GET /docs on the same router as your API.http://localhost:3000/docs in a browser to see the Swagger UI.3
Annotate routes with #[openapi]
Enrich individual handlers with a custom summary, tag, or response codes. Handlers without annotations get sensible defaults.
Customize with OpenApiOptions
When you need to set the API title, version, server URLs, or security schemes, replaceenable_openapi() with enable_openapi_with_options(OpenApiOptions { ... }).
OpenApiOptions have defaults — use ..Default::default() and override only what you need.
Add schemas to components
nestrs-openapi does not derive request/response schemas from Rust types. Provide them manually undercomponents.schemas. The #[openapi(responses = ...)] attribute on handlers sets status codes and descriptions but not content or $ref links.
Global security scheme
Declare a security scheme undercomponents.securitySchemes and reference it in the root security array to apply it to all operations in the Swagger UI.
Per-route security from #[roles]
When handlers use#[roles("admin")], the macro stores roles metadata in MetadataRegistry. Setting infer_route_security_from_roles: true tells nestrs-openapi to add a security array to those operations automatically, so Swagger UI shows a lock icon only on protected routes.
#[roles("admin")] get "security": [{ "bearerAuth": [] }] in the generated document. Routes without #[roles] are left unchanged.
Standalone router
If you manage your own Axum router rather than usingNestApplication, import openapi_router from nestrs-openapi directly and merge the returned Router into your app.
api_prefix so the documented paths in openapi.json match the actual URLs your application serves.