修改 NestJS 中 OpenAPI (Swagger) 架构中出现的 DTO 名称

Ext*_*ely 6 schema dto swagger openapi nestjs

我面临一个问题,我的 DTO 类型被命名为一件事,但我希望它们在 OpenAPI 文档页面中以不同的名称出现。例如,我有一个在控制器中使用的 UserDto 类,但希望它在模式部分(以及这适用的其他任何地方)中仅显示为“User”。那可能吗?有我可以使用的装饰器吗?我知道我可以简单地修改类名,但在其他地方已经使用了不同的用户类。我到处寻找都没有结果。

在此输入图像描述

顺便说一句,我正在使用 typescript 和 Nestjs。每一个帮助将不胜感激,谢谢!

小智 6

Nest.js 尚未提供现成的解决方案。有一个开放的拉取请求(如前所述)https://github.com/nestjs/swagger/pull/983,但何时合并尚不清楚。您可以使用以下方法之一更改架构中的 DTO 名称:

  1. 将静态名称属性添加到您的 DTO。
  class UserDto {
    static name = 'User';  // <- here

    @ApiProperty()
    firstName: string;

    // ...
  }
Run Code Online (Sandbox Code Playgroud)

但在严格模式下,TypeScript 会显示如下错误: Static property 'name' conflicts with built-in property 'Function.name' of constructor function 'UserDto'.

  1. 按照拉取请求中的建议编写一个带有接口的装饰器并使用它,直到所需的功能出现在 Nest.js 中。装饰器将具有所需值的 name 属性添加到 DTO 的包装类中。
  type Constructor<T = object> = new(...args: any[]) => T;
  type Wrapper<T = object> = { new(): (T & any), prototype: T };
  type DecoratorOptions = { name: string };
  type ApiSchemaDecorator = <T extends Constructor>(options: DecoratorOptions) => (constructor: T) => Wrapper<T>;

  const ApiSchema: ApiSchemaDecorator = ({ name }) => {
    return (constructor) => {
      const wrapper = class extends constructor { };
      Object.defineProperty(wrapper, 'name', {
        value: name,
        writable: false,
      });
      return wrapper;
    }
  }
Run Code Online (Sandbox Code Playgroud)

按照提案中的建议使用:

  @ApiSchema({ name: 'User' }) // <- here
  class UserDto {
    @ApiProperty()
    firstName: string;

    // ...
  }
Run Code Online (Sandbox Code Playgroud)

并且不要忘记,在 TypeScript 5 中,装饰器 API 将更改为接近 JavaScript 中的实现