在 POST 上动态更改 @Body 类型
Dynamically change @Body type on POST
我创建了一个 class 来从我的控制器中扩展,所以在我的 POST 中,当我像这样定义 BODY 参数时
@Body() create: any
但我正在使用 swagger,所以我想显示架构。
我试过这种方法:
type dto = {
one: OneDto
two: TwoDto
}
然后
@Body() create: dto['one']
但无论如何它都没有显示架构。
有什么建议吗?
类型在运行时不存在,AFIAK @nestjs/swagger
插件在运行时依赖它们。所以你甚至不能使用@Body() create: InterfaceCreate
。你必须有一些具体的class
这可能会帮助您解决:How to generate Generics DTO with nestjs/swagger(一个 post 由一个对 @nestjs/swagger
包贡献很大的人制作的)
我解决这个问题不是通过动态更改类型,而是创建一个控制器工厂。我用这个
并根据我的需要进行修改。
export function CrudController<T, C, U, Q>(
createDto: Type<C>,
updateDto: Type<U>,
queryDto: Type<Q>
): Type<ICrudController<T, C, U, Q>> {
const createPipe = new AbstractValidationPipe(
{ /* whitelist: true, */ transform: true /* forbidNonWhitelisted: true */ },
{ body: createDto }
);
const updatePipe = new AbstractValidationPipe(
{ /* whitelist: true, */ transform: true },
{ body: updateDto }
);
const queryPipe = new AbstractValidationPipe(
{ /* whitelist: true, */ transform: true },
{ query: queryDto }
);
class CRUD<T, C, U, Q> implements ICrudController<T, C, U, Q> {
constructor(protected readonly service: CrudService<T, C, U, Q>) {}
// protected ;
@Post()
@UsePipes(createPipe)
@ApiBody({ type: createDto })
@ApiCreatedResponse({
description: "Created succesfully.",
type: CreatedDto,
})
@ApiBadRequestResponse({ type: ResponseDto })
@ApiForbiddenResponse({ type: ResponseDto })
@ApiConflictResponse({ type: ResponseDto })
create(
@Body() body: C
) {
return this.service.createAsync(body);
}
@Get()
@UsePipes(queryPipe)
@ApiOkResponse({ description: "Retrieved succesfully.", type: queryDto })
@ApiBadRequestResponse({ type: ResponseDto })
@ApiForbiddenResponse({ type: ResponseDto })
read(): Promise<any> {
return this.service.readAsync();
}
@Get(":id")
@ApiOkResponse({ description: "Retrieved succesfully.", type: queryDto })
@ApiBadRequestResponse({ type: ResponseDto })
@ApiForbiddenResponse({ type: ResponseDto })
readOne(
@Param("id", ParseIntPipe) id: number
): Promise<Q> {
return this.service.readAsync(null, { id: id });
}
@Patch(":id")
@UsePipes(updatePipe)
@ApiBody({ type: updateDto })
@ApiBadRequestResponse({ type: ResponseDto })
@ApiForbiddenResponse({ type: ResponseDto })
update(
@Param("id", ParseIntPipe) id: number,
@Body() body: U
): any {
return this.service.updateAsync(body, { id: id });
}
@Delete(":id")
@ApiBadRequestResponse({ type: ResponseDto })
@ApiForbiddenResponse({ type: ResponseDto })
delete(
@Param("id", ParseIntPipe) id: number
): any {
return this.service.deleteAsync(id);
}
}
return CRUD;
}
我创建了一个 class 来从我的控制器中扩展,所以在我的 POST 中,当我像这样定义 BODY 参数时
@Body() create: any
但我正在使用 swagger,所以我想显示架构。 我试过这种方法:
type dto = {
one: OneDto
two: TwoDto
}
然后
@Body() create: dto['one']
但无论如何它都没有显示架构。 有什么建议吗?
类型在运行时不存在,AFIAK @nestjs/swagger
插件在运行时依赖它们。所以你甚至不能使用@Body() create: InterfaceCreate
。你必须有一些具体的class
这可能会帮助您解决:How to generate Generics DTO with nestjs/swagger(一个 post 由一个对 @nestjs/swagger
包贡献很大的人制作的)
我解决这个问题不是通过动态更改类型,而是创建一个控制器工厂。我用这个
export function CrudController<T, C, U, Q>(
createDto: Type<C>,
updateDto: Type<U>,
queryDto: Type<Q>
): Type<ICrudController<T, C, U, Q>> {
const createPipe = new AbstractValidationPipe(
{ /* whitelist: true, */ transform: true /* forbidNonWhitelisted: true */ },
{ body: createDto }
);
const updatePipe = new AbstractValidationPipe(
{ /* whitelist: true, */ transform: true },
{ body: updateDto }
);
const queryPipe = new AbstractValidationPipe(
{ /* whitelist: true, */ transform: true },
{ query: queryDto }
);
class CRUD<T, C, U, Q> implements ICrudController<T, C, U, Q> {
constructor(protected readonly service: CrudService<T, C, U, Q>) {}
// protected ;
@Post()
@UsePipes(createPipe)
@ApiBody({ type: createDto })
@ApiCreatedResponse({
description: "Created succesfully.",
type: CreatedDto,
})
@ApiBadRequestResponse({ type: ResponseDto })
@ApiForbiddenResponse({ type: ResponseDto })
@ApiConflictResponse({ type: ResponseDto })
create(
@Body() body: C
) {
return this.service.createAsync(body);
}
@Get()
@UsePipes(queryPipe)
@ApiOkResponse({ description: "Retrieved succesfully.", type: queryDto })
@ApiBadRequestResponse({ type: ResponseDto })
@ApiForbiddenResponse({ type: ResponseDto })
read(): Promise<any> {
return this.service.readAsync();
}
@Get(":id")
@ApiOkResponse({ description: "Retrieved succesfully.", type: queryDto })
@ApiBadRequestResponse({ type: ResponseDto })
@ApiForbiddenResponse({ type: ResponseDto })
readOne(
@Param("id", ParseIntPipe) id: number
): Promise<Q> {
return this.service.readAsync(null, { id: id });
}
@Patch(":id")
@UsePipes(updatePipe)
@ApiBody({ type: updateDto })
@ApiBadRequestResponse({ type: ResponseDto })
@ApiForbiddenResponse({ type: ResponseDto })
update(
@Param("id", ParseIntPipe) id: number,
@Body() body: U
): any {
return this.service.updateAsync(body, { id: id });
}
@Delete(":id")
@ApiBadRequestResponse({ type: ResponseDto })
@ApiForbiddenResponse({ type: ResponseDto })
delete(
@Param("id", ParseIntPipe) id: number
): any {
return this.service.deleteAsync(id);
}
}
return CRUD;
}