Create a custom response in Swagger Nestjs

Viewed 1467

I have my controller with

  @Post('email/register')
  @HttpCode(HttpStatus.CREATED)
  @ApiOkResponse(AuthConfigSwagger.API_OP_CREATE)
  @ApiCreatedResponse(AuthConfigSwagger.API_RES_CREATE)
  async register(@Body() authRegisterLoginDto: AuthRegisterLoginDto) {
    return this.authService.register(authRegisterLoginDto);
  }

where AuthConfigSwagger.API_RES_CREATE is

static readonly API_RES_CREATE: ApiResponseOptions = {
    description: 'The user has been successfully created.',
    type: User
  };

the response is not the real response that I create. In that way, I show the entire document (I'm using mongoDb)

I need to put my custom response, like

{
  "statusCode": 201,
  "message": "",
  "status": "success"
}

And Sometimes I need to use User properties.

I read the documentation, and I can't find any properties for custom response.

UPDATE:

I can create a class like:

import { ApiProperty } from "@nestjs/swagger";

export class successResponse {

    @ApiProperty({
        example: 'success',
        description: 'status',
    })
    status: string;
    @ApiProperty({
        description: 'status',
    })
    message?: string;

    @ApiProperty({
        description: 'could contain some info',        
    })
    data?: object;
    
}

And I have

{
  "status": "success",
  "message": "string",
  "data": {}
}

in my Example value on swagger. But, for example in the Login route, I'd like to see something like that on 200 Response:

{
  "data": {
    "expiresIn": number,
    "accessToken": "string",
    "user": {
      "name": "string",
      "email": "string",
      "id": "string"
    }
  },
  "statusCode": number,
  "status": "string"
}

I don't want to create a custom response for each API.

2 Answers

Use an Interface for example.

interface IResponseWrapper<T>{ 
  status: string;
  statusCode: number;
  data: T
}

Now use this Interface to extends your class

After creating your "successResponse" class, you need to include it in the @ApiResponse() decorator. Inside the "type" option

Also, I changed the class name from "successResponse" to "SucessResponse". It makes it easier to distinguish between classes and methods.

@Post('email/register')
@HttpCode(HttpStatus.CREATED)
@ApiOkResponse(AuthConfigSwagger.API_OP_CREATE)
@ApiResponse({type: SuccessResponse})
@ApiCreatedResponse(AuthConfigSwagger.API_RES_CREATE)
async register(@Body() authRegisterLoginDto: AuthRegisterLoginDto) {
    return this.authService.register(authRegisterLoginDto);
}

This will make swagger know the response type for that endpoint.

Also, you may want to create some extra classes to see all the fields you want.

import { ApiProperty } from "@nestjs/swagger";

export class UserData{
    @ApiProperty()
    name: string

    @ApiProperty()
    email: string

    @ApiProperty()
    id: string
}

export class DataResponse {
    @ApiProperty()
    expiresIn: number,

    @ApiProperty()
    accessToken: "string",

    @ApiProperty({type: UserData})
    user: UserData
}

export class SuccessResponse {

    @ApiProperty({
        example: 'success',
        description: 'status',
    })
    status: string;
    @ApiProperty({
        description: 'status',
    })
    message?: string;

    @ApiProperty({
        description: 'could contain some info',  
        type: DataResponse      
    })
    data?: DataResponse;
}

and then you add to your endpoint like so

@Post('email/register')
@HttpCode(HttpStatus.CREATED)
@ApiOkResponse(AuthConfigSwagger.API_OP_CREATE)
@ApiResponse({type: SuccessResponse})
@ApiCreatedResponse(AuthConfigSwagger.API_RES_CREATE)
async register(@Body() authRegisterLoginDto: AuthRegisterLoginDto) {
    return this.authService.register(authRegisterLoginDto);
}
Related