javascript - 装饰器在 Nest Controller 中返回 404

标签 javascript node.js nestjs

我正在使用 NestJS 开发后端(顺便说一句,这太棒了)。我有一个“标准获取实体情况的单个实例”,类似于下面的示例。

@Controller('user')
export class UserController {
    constructor(private readonly userService: UserService) {}
    ..
    ..
    ..
    @Get(':id')
    async findOneById(@Param() params): Promise<User> {
        return userService.findOneById(params.id);
    }

这非常简单并且有效 - 但是,如果用户不存在,服务将返回未定义并且 Controller 返回 200 状态代码和空响应。

为了让 Controller 返回 404,我想到了以下方法:

    @Get(':id')
    async findOneById(@Res() res, @Param() params): Promise<User> {
        const user: User = await this.userService.findOneById(params.id);
        if (user === undefined) {
            res.status(HttpStatus.NOT_FOUND).send();
        }
        else {
            res.status(HttpStatus.OK).json(user).send();
        }
    }
    ..
    ..

这行得通,但更代码化(是的,它可以重构)。

这真的可以使用装饰器来处理这种情况:

    @Get(':id')
    @OnUndefined(404)
    async findOneById(@Param() params): Promise<User> {
        return userService.findOneById(params.id);
    }

有谁知道装饰器可以做到这一点,或者有比上面那个更好的解决方案吗?

最佳答案

最短的方法是

@Get(':id')
async findOneById(@Param() params): Promise<User> {
    const user: User = await this.userService.findOneById(params.id);
    if (user === undefined) {
        throw new BadRequestException('Invalid user');
    }
    return user;
}

装饰器在这里没有意义,因为它会有相同的代码。

注意 BadRequestException是从@nestjs/common导入的;

编辑

一段时间后,我想到了另一个解决方案,它是 DTO 中的装饰器:

import { registerDecorator, ValidationArguments, ValidationOptions, ValidatorConstraint } from 'class-validator';
import { createQueryBuilder } from 'typeorm';

@ValidatorConstraint({ async: true })
export class IsValidIdConstraint {

    validate(id: number, args: ValidationArguments) {
        const tableName = args.constraints[0];
        return createQueryBuilder(tableName)
            .where({ id })
            .getOne()
            .then(record => {
                return record ? true : false;
            });
    }
}

export function IsValidId(tableName: string, validationOptions?: ValidationOptions) {
    return (object, propertyName: string) => {
        registerDecorator({
            target: object.constructor,
            propertyName,
            options: validationOptions,
            constraints: [tableName],
            validator: IsValidIdConstraint,
        });
    };
}

然后在你的 DTO 中:

export class GetUserParams {
    @IsValidId('user', { message: 'Invalid User' })
    id: number;
}

希望对大家有帮助。

关于javascript - 装饰器在 Nest Controller 中返回 404,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49709429/

相关文章:

javascript - 将 GET 请求(HTML 字符串)转换为完整的 DOM 对象

javascript - 定时调用API

javascript - 如何修复 Node 终端中的 'variable is not defined' 以及为什么会发生这种情况?

javascript - 在初始化时运行程序

NestJs/招摇 : Define ref schemas without DTO classes

javascript - IE : HTML select with huge options taking lot of time in loading

javascript - 浏览器渲染和 javascript 执行的同步/异步特性

javascript - 有没有有效的方法将数据设置到MapObject?

node.js - 如何在命令行上将分层配置值传递给 nconf?

javascript - 在 NestJs 中,如何根据其接口(interface)注入(inject)服务?