In Nestjs you can use @Query() query: MyDto
to automatically validate your query params, and to generate a Swagger documentation.
I've created a custom decorator, that kinda replaces the @Query
decorator. My custom decorator does a few things differently.
BUT, I can't find a way to generate the Swagger documentation automatically, for example:
Using @Query
:
Swagger screenshot with param documented
Controller:
@Get()
findAll(@Query() query: AqpDto, @Tenant() tenantId: string) {
return this.logsService.findAll(query, tenantId);
}
Using my decorator: Swagger screenshot without params
@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.
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. 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.
CodePudding user response:
The Query()
related code can be found in the @nestjs/common
package, in the route-params.decorator.ts
file.
It doesn't do anything with Swagger, and it shouldn't, that's not its responsibility.
export function Query(
property?: string | (Type<PipeTransform> | PipeTransform),
...pipes: (Type<PipeTransform> | PipeTransform)[]
): ParameterDecorator {
return createPipesRouteParamDecorator(RouteParamtypes.QUERY)(
property,
...pipes,
);
}
The @Body()
, @Query()
, @Param()
...etc. decorators all have a very similar implementation. They all call the createPipesRouteParamDecorator(...)
function with a RouteParamtypes
value.
export enum RouteParamtypes {
BODY,
QUERY,
PARAM,
...
}
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.
The @nestjs/swagger
packages uses the constants under which this metadata is saved and gathers this metadata (using Reflect.getMetadata()
).
For example:
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. You can tweak this by adding extra decorators provided by the @nestjs/swagger
package. With these you can provide extra metadata that is gathered to help generate the Swagger documenation. In your case you can use the @ApiQuery()
decorator to provide extra hints.
@ApiQuery({
name: 'query',
schema: { .... },
type: AqpDto,
required: true
})
@Get()
findAll(@Aqp() query: AqpDto, @Tenant() tenantId: string) {
...
}