Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NestJs/swagger: Define ref schemas without DTO classes

I have an app where I define the API response schemas as plain javascript objects according to the open-api spec. Currently I am passing that to the ApiResponse decorator in @nestjs/swagger as follows:

class CatsController {

  @Get()
  @ApiResponse({
    status: 200,
    schema: catSchema // plain js object imported from another file
  })
  getAll() {}
}

This is working great. However, the output open-api spec contains the verbose schema for every endpoint which uses the catSchema. Instead, I want the output swagger file to have the catSchema under the components section, and have a corresponding $ref in the paths section.

components:
  schemas:
    Cat:
      properties:
        name:
          type: string
paths:
  /cats/{id}:
    get:
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Cat'

So far, it seems the only way to do that would be to define the schema as a DTO class and use the ApiProperty decorator for each class property. In my case, that means I have to refactor all the plain object schemas in open-api spec to be DTO classes.

Is there a way to feed the raw schema to the library and get the expected outcome?

// instead of this:
class CatDto {
  @ApiProperty()
  name: string;
}

// I want to do:
const catSchema = {
  type: 'object',
  properties: {
    name: { type: 'string' }
  }
}
like image 516
Pubudu Dodangoda Avatar asked Feb 25 '26 03:02

Pubudu Dodangoda


1 Answers

I guess this can also be achieved with using getSchemaPath and ApiExtraModels:

import { ApiExtraModels, ApiResponse, getSchemaPath } from '@nestjs/swagger';

@ApiExtraModels(CatDto) // for CatDto to be found by getSchemaPath()
@ApiResponse({
  schema: {
    '$ref': getSchemaPath(CatDto)
  }
})

More on extra models: https://docs.nestjs.com/openapi/types-and-parameters#extra-models


In my case, that means I have to refactor all the plain object schemas in open-api spec to be DTO classes.

You don't need to manually annotate objects, you can also use this plugin, which is opt-in: https://docs.nestjs.com/openapi/cli-plugin

like image 55
Anastazy Avatar answered Feb 27 '26 03:02

Anastazy



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!