NestJS:传入null DTO时禁用生成对应创建API的需求
实现方案
要实现传入createEntityDto为null时不生成创建接口,核心思路是在工厂函数中动态决定是否为基础控制器添加createEntity方法及对应的装饰器——因为NestJS的装饰器在类定义阶段就会执行,直接在类内部写条件判断无法控制装饰器是否生效。
具体代码修改
1. 调整工厂函数逻辑
修改BaseControllerFactory,先定义基础控制器的公共方法,再根据createEntityDto是否为null动态添加创建接口:
export function BaseControllerFactory<E>( createEntityDto: typeof CreateEntityDto | null, // 允许传入null updateEntityDto: typeof UpdateEntityDto, entityToViewDto: ViewDtoContructor<E>, ): Type<IBaseController<E>> { class BaseController implements IBaseController<E> { constructor(private readonly baseService: BaseService<E>) {} @Get() @ApiOperation({ summary: 'Get entities' }) async getEntities(@Query(ValidationPipe) getEntitiesDto: GetEntitiesDto) { // 原有查询逻辑 } // ...保留其他公共方法 } // 仅当createEntityDto不为null时,添加创建接口 if (createEntityDto) { // 定义创建方法的逻辑 const createEntity = async function(this: BaseController, @Body(ValidationPipe) dto: typeof CreateEntityDto) { // 原有创建逻辑,例如调用服务层方法 const entity = await this.baseService.create(dto); return new entityToViewDto(entity); }; // 手动为方法应用Nest装饰器 Post()(BaseController.prototype, 'createEntity', Object.getOwnPropertyDescriptor(BaseController.prototype, 'createEntity')!); ApiOperation({ summary: 'Create new entity' })(BaseController.prototype, 'createEntity', Object.getOwnPropertyDescriptor(BaseController.prototype, 'createEntity')!); ApiBody({ type: createEntityDto })(BaseController.prototype, 'createEntity', Object.getOwnPropertyDescriptor(BaseController.prototype, 'createEntity')!); // 将方法挂载到控制器类的原型上 BaseController.prototype.createEntity = createEntity; } return BaseController; }
2. 调用工厂函数时传入null
在UsersController中传入null,即可隐藏创建接口:
@ApiTags('Users') @Controller('users') export class UsersController extends BaseControllerFactory<User>( null, // 传入null,不生成创建接口 UpdateUserDto, UserToViewDto, ) { constructor(private readonly userService: UsersService) { super(userService); } }
原理说明
NestJS的装饰器本质是增强类/方法的函数,会在类定义阶段执行。通过动态判断参数、手动挂载方法并应用装饰器,能精准控制哪些方法被暴露为API接口——当createEntityDto为null时,跳过创建方法的添加流程,最终生成的控制器类就不会包含创建接口。
内容的提问来源于stack exchange,提问作者Đoàn Đức Bảo
相关产品推荐
相关产品推荐

