About NestJS

NestJS 自定义 Swagger 装饰器

https://docs.nestjs.com/openapi/operations#advanced-generic-apiresponse

比如统一泛型返回类型

typescript
1
2
3
4
5
6
7
8
9
type ApiResponse<T> = {
  timestamp: string;

  path: string;

  pathViewCount: number;

  data: T;
}

但是 Swagger ApiResponse 并不能使用泛型,只能使用 Class。
可以使用自定义如下注解实现类似效果

typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import type { Type } from '@nestjs/common';
import { applyDecorators } from '@nestjs/common';
import { ApiExtraModels, ApiOkResponse, ApiResponseProperty, getSchemaPath } from '@nestjs/swagger';
import type { ReferenceObject } from '@nestjs/swagger/dist/interfaces/open-api-spec.interface';

class ResponseInterceptorResult {
  @ApiResponseProperty()
  timestamp: string;

  @ApiResponseProperty()
  path: string;

  @ApiResponseProperty()
  pathViewCount: number;
}

export const ApiOkInterceptorResultResponse = <T extends Type>(options: {
  model: T;
  description?: string;
  isArray?: boolean;
}) => {
  const { model, description, isArray } = options;
  const ref: ReferenceObject = { $ref: getSchemaPath(model) };
  return applyDecorators(
    ApiExtraModels(ResponseInterceptorResult),
    ApiExtraModels(model),
    ApiOkResponse({
      description,
      schema: {
        allOf: [
          {
            $ref: getSchemaPath(ResponseInterceptorResult),
          },
          {
            properties: {
              data: isArray ? { type: 'array', items: ref } : ref,
            },
          },
        ],
      },
    }),
  );
};

Swagger Cli Plugin

This plugin is opt-in. If you prefer, you can declare all decorators manually, or only specific decorators where you need them.