简体   繁体   English

带有 Swagger 文档的自定义参数装饰器

[英]Custom param decorator with Swagger documentation

In Nestjs you can use @Query() query: MyDto to automatically validate your query params, and to generate a Swagger documentation.在 Nestjs 中,您可以使用@Query() query: MyDto自动验证您的查询参数,并生成 Swagger 文档。

I've created a custom decorator, that kinda replaces the @Query decorator.我创建了一个自定义装饰器,它有点取代了@Query装饰器。 My custom decorator does a few things differently.我的自定义装饰器做了一些不同的事情。

BUT, I can't find a way to generate the Swagger documentation automatically, for example:但是,我找不到自动生成 Swagger 文档的方法,例如:

Using @Query : Swagger screenshot with param documented使用@Query带有参数的 Swagger 屏幕截图

Controller:控制器:

@Get()
  findAll(@Query() query: AqpDto, @Tenant() tenantId: string) {
    return this.logsService.findAll(query, tenantId);
  }

Using my decorator: Swagger screenshot without params使用我的装饰器:不带参数的 Swagger 截图

@Get()
  findAll(@Aqp() query: AqpDto, @Tenant() tenantId: string) {
    return this.logsService.findAll(query, tenantId);
  }

I consume these APIs using swagger-client so the lack of the query param definitions is not only missing documentation, but also breaks the API call, as swagger-client doesn't send the params as expected.我使用swagger-client使用这些 API,因此缺少查询参数定义不仅缺少文档,而且还会中断 API 调用,因为swagger-client没有按预期发送参数。

I've tried applyDecorators , I tried to find ways to automatically execute the Query once my decorator is called, I tried to find the source code of Query to identify how it adds the Dto params to Swagger.我已经尝试过applyDecorators ,我试图找到在调用我的装饰器后自动执行Query的方法,我试图找到Query的源代码来确定它如何将Dto参数添加到 Swagger。 I don't know what else to do do.我不知道还能做什么。

I'm trying to find a clean solution, but no luck so far.我正在尝试找到一个干净的解决方案,但到目前为止还没有运气。 Any help is appreciated.任何帮助表示赞赏。

The Query() related code can be found in the @nestjs/common package, in the route-params.decorator.ts file. Query()相关代码可以在@nestjs/common包的route-params.decorator.ts文件中找到。

https://github.com/nestjs/nest/blob/master/packages/common/decorators/http/route-params.decorator.ts#L411 https://github.com/nestjs/nest/blob/master/packages/common/decorators/http/route-params.decorator.ts#L411

It doesn't do anything with Swagger, and it shouldn't, that's not its responsibility.它对 Swagger 没有任何作用,也不应该,这不是它的责任。

export function Query(
  property?: string | (Type<PipeTransform> | PipeTransform),
  ...pipes: (Type<PipeTransform> | PipeTransform)[]
): ParameterDecorator {
  return createPipesRouteParamDecorator(RouteParamtypes.QUERY)(
    property,
    ...pipes,
  );
}

The @Body() , @Query() , @Param() ...etc. @Body()@Query()@Param() ...等。 decorators all have a very similar implementation.装饰器都有一个非常相似的实现。 They all call the createPipesRouteParamDecorator(...) function with a RouteParamtypes value.它们都使用RouteParamtypes值调用createPipesRouteParamDecorator(...)函数。

export enum RouteParamtypes {
  BODY,
  QUERY,
  PARAM,
  ...
}

https://github.com/nestjs/nest/blob/master/packages/common/enums/route-paramtypes.enum.ts https://github.com/nestjs/nest/blob/master/packages/common/enums/route-paramtypes.enum.ts

In the end it uses Reflect.defineMetadata(...) to set metadata on the controller about the query, body, param...etc.最后,它使用Reflect.defineMetadata(...)在控制器上设置有关查询、正文、参数...等的元数据。

The @nestjs/swagger packages uses the constants under which this metadata is saved and gathers this metadata (using Reflect.getMetadata() ). @nestjs/swagger包使用保存此元数据的常量并收集此元数据(使用Reflect.getMetadata() )。

For example:例如:

https://github.com/nestjs/swagger/blob/master/lib/services/parameter-metadata-accessor.ts https://github.com/nestjs/swagger/blob/master/lib/services/parameter-metadata-accessor.ts

Based on the gathered metadata its able to construct the Swagger documentation.基于收集到的元数据,它能够构建 Swagger 文档。 You can tweak this by adding extra decorators provided by the @nestjs/swagger package.您可以通过添加@nestjs/swagger包提供的额外装饰器来调整它。 With these you can provide extra metadata that is gathered to help generate the Swagger documenation.有了这些,您可以提供额外的元数据,这些元数据可以帮助生成 Swagger 文档。 In your case you can use the @ApiQuery() decorator to provide extra hints.在您的情况下,您可以使用@ApiQuery()装饰器来提供额外的提示。

@ApiQuery({ 
  name: 'query', 
  schema: { .... },
  type: AqpDto,
  required: true
})
@Get()
findAll(@Aqp() query: AqpDto, @Tenant() tenantId: string) {
  ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM