OpenAPI Swagger reusable schema parts

I'm having some challenges while creating the swagger reusable schema components.

I have a lot of APIs in the project and most of them have the same headers and common error responses, of course, every API has its different response schema, to overcome this challenge I have created a decorator as bellow:

swagger-essentials.decorator.ts

type apiOkResponse = Type<unknown>;

export const SwaggerEssentials = (okRes?: apiOkResponse) => {
  return applyDecorators(
    SwaggerApiHeaders(),
    ApiResponse({ type: okRes, status: 200 }),
    HttpCode(200),
    ApiResponse({ type: ConnectTimeoutDTO, status: 599 }),
    ApiResponse({ type: JsonValidationErrorDTO, status: 501 }),
    SwaggerCommonResponses(),
  );
};

response.dto.ts

class Response {
  @ApiProperty()
  id: number;

  @ApiProperty()
  name:string;
}

export class RESPONSE_SCHEMA {
  @ApiProperty({ example: 'Success' })
  message: string;

  @ApiProperty({example: {}})
  data: Response;
}

And then in my controller, I use it like below:

xyz.controller.ts

@Post('/test')
@SwaggerEssentials(RESPONSE_SCHEMA)
fetchDetails(){}

Till here everything is fine and no problem, but as every API has its different response, however, there are two properties that remain the same in case of a successful response which are message and data of course the data will be different.

So, I want to have something through which I can get rid of above mentioned two properties and they are automatically defined/attached to the actual response.

I have tried PartialType() but it's not worthy to solve this problem.

Upvotes: 4

Views: 1539

Answers (1)

Aditya Gaddhyan
Aditya Gaddhyan

Reputation: 364

This seems to be something that I too faced. But there are some downside of the code. RESPONSE_SCHEMA which should have been generic to accumulate any type of data is tightly bound to Response class. This can be fixed with the help of generics:

export class RESPONSE_SCHEMA <T = any>{
   data: T;
   message : string;
   headers?: Record<string, string>;
}

Now your controller function instead will return this:

@Post('/test')
@SwaggerEssentials(RESPONSE_SCHEMA)
fetchDetails():RESPONSE_SCHEMA<Response>{}

By this, you can get the desired response object in your swagger.

Also, you can remove the function parameter in SwaggerEssentials and try. It should work. Also, please recheck SwaggerApiHeaders() and SwaggerCommonResponses(). These don't seem to be classes in swagger module.

Upvotes: 1

Related Questions