i.brod
i.brod

Reputation: 4613

How to define the response body object, in a NestJs-generated Swagger document?

I'm Using NestJs and its Swagger plugin to auto-generate documentation of my API.

Problem is, I cant figure out how to make the response schema appear in the documentation. In my GET routes, all i get is "Code 200", with no data structure.

I have a typical setup, where a controller method uses a corresponding service method, which in turn uses a TypeOrm repository. For example:

@Get()
 findAll() {    
   return this.usersService.findAll();
}

I tried using the @ApiResponse decorator, but didn't really see any way to make it serve this purpose. Also, creating a user.dto.ts and making it the return type of the controller route didn't do any good.

Eventually, this is what i get in the Swagger:

swagger

How can i define the response body schema?

Upvotes: 23

Views: 45900

Answers (3)

Hicham
Hicham

Reputation: 31

Also, creating a user.dto.ts and making it the return type of the controller route didn't do any good.

I faced a similar issue, yet adding type annotation to the controller route / service method did it for me (also using the Swagger CLI plugin).

import { User } from './entities/user.entity';

@Get()
findAll(): Promise<User[]> {    
  return this.usersService.findAll();
}

This changed the Swagger specs for the endpoint response

{
  // ...
        "responses": {
          "200": {
            "description": "",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
-                    "type": "object"
+                    "$ref": "#/components/schemas/User"
                  }
                }
              }
            }
          }
        },
  // ...
}

and added the User schema.

Upvotes: 0

xstefi
xstefi

Reputation: 581

You can annotate controller action with ApiExtraModels:

import { ApiExtraModels, ApiResponse, getSchemaPath } from '@nestjs/swagger'
import { Controller, Get, Param } from '@nestjs/common';

@Controller('users')
export class UsersController {


 @ApiExtraModels(UserDto)
 @ApiResponse({
    status: 200,
    schema: {
      $ref: getSchemaPath(UserDto),
    },
  })
  @Get('/:userId')
  getById(@Param('userId') userId: string): UserDto {
     ... something happens ... 
     return myUserDto;
  }

}

and you have to also annotate UserDto properties with ApiProperty:

import { ApiProperty } from '@nestjs/swagger'
import { Expose } from 'class-transformer'
import { IsString } from 'class-validator'

export class UserDto {

  @ApiProperty()
  @IsString()
  @Expose()
  id: string;
}

Btw, check CLI plugin for generating ApiProperty

Upvotes: 12

Jesse Carter
Jesse Carter

Reputation: 21167

You can use the type and isArray properties in conjunction with the ApiResponse family of decorators. For example:

@ApiOkResponse({
    description: 'The user records',
    type: User,
    isArray: true
})
@Get()
 findAll() {    
   return this.usersService.findAll();
}

Additionally, consider using the Swagger CLI plugin to help you have these decorators applied automatically during build time instead of you having to keep everything in sync manually.

Upvotes: 30

Related Questions