OpenAPI Decorators

OpenAPI Documentation from Decorators

@nestjs/swagger builds the document OpenAPI assembled by hand, from metadata that is already there. Routes come from @Get/@Post, parameters from @Param/@Query, request bodies from the DTO classes, and constraints from their class-validator decorators. You add titles and examples, never the shape.

src/bootstrap.ts — the document and the viewerTypeScript
const config = new DocumentBuilder().setTitle('Bookshelf API').setVersion('1.0.0')
  .addServer('https://api.example.com').addBearerAuth().build();
SwaggerModule.setup('docs', app, SwaggerModule.createDocument(app, config),
                    { jsonDocumentUrl: 'openapi.json' });   // UI at /docs, JSON alongside

For the Bookshelf routes that generated five paths and four component schemas, with the minimum and the enum read straight off the decorators:

Output of 114
$ curl -s localhost:4310/openapi.json | python -m json.tool     # 3.0.0, 5 paths, 4 schemas
"CreateBookDto": { "type": "object", "required": ["title","authorId","year","genre"],
  "properties": { "title": { "type": "string", "example": "Solaris" },
    "year":  { "type": "number", "example": 1961, "minimum": 1450 },
    "genre": { "type": "string", "enum": ["fantasy","sci-fi","history","other"] } } }
"/api/v1/books": { "get": { "parameters": [ { "name": "limit", "in": "query",
    "schema": { "maximum": 100, "default": 20, "type": "number" } } ] },
  "post": { "operationId": "BooksController_create_api/v1",
    "security": [{"bearer": []}], "responses": { "201": { "description": "" } } } }

Three details are worth fixing before you publish. createDocument emits OpenAPI 3.0.0 by default; setOpenAPIVersion('3.1.0') raises it. The generated operationId becomes an ugly method name in any generated client — @ApiOperation({ operationId: 'createBook' }) replaces it. And the empty 201 description is all Nest can infer: response bodies come from @ApiOkResponse({ type: BookDto }), the one place you must restate a shape.