首页 > 解决方案 > api 数据验证的最佳实践

问题描述

我正在努力创建 api with nestjs,但是当涉及到数据验证时,由于存在许多选项,它变得如此混乱,例如,我应该使用模式验证(如hapi@joi)在 rout 级别验证数据还是在类级别 class-validator 中验证数据

`

use(req: Request, res: Response, next: Function) {
    console.log('the method is', req.method);

const userSchema = joi.object({
  name: joi
    .string()
    .alphanum()
    .min(3)
    .max(15)
    .required(),
  phone: joi
    .number()
    .min(11)
    .required(),
  password: joi
    .string()
    .min(8)
    .max(100)
    .required()
    .regex(/((?=.*\d)|(?=.*\w+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/),
});
const { error } = userSchema.validate(req.body);
if (error) {
  throw new BadRequestException(error.details);
}
next();

`

类级别的验证

`

export class CreateUserDto {
  @IsString()
  @IsNotEmpty()
  name: string;

  @IsNotEmpty()
  @IsString()
  @Matches(/((?=.*\d)|(?=.*\w+))(?![.\n])(?=.*[A-Z])(?=.*[a-z]).*$/)
  password: string;

  @IsNumber()
  @Length(11, 15)
  @IsNotEmpty()
  phone: number;
}

`

标签: typescriptapinestjs

解决方案


NestJs Pipes文档页面提供了使用基于模式的验证类验证器技术的示例,并且似乎并不喜欢其中一个。在大多数情况下,遵循 NestJs 约定优于第一个示例中使用的中间件技术。

根据实体的数量和需求更改的频率,使用第一种技术可能难以保持模式同步。

您的第二个示例可能更容易维护,因为您的验证是使用您的实体定义的。当实体更改时,您不必记住编辑另一个文件。

如果您使用任何第 3 方软件包,它可能具有对其中一种或另一种的内置支持。例如,该@nestjsx/crud包使用 NestJs 内置的ValidationPipeBody 请求验证,利用类验证器和类转换器库。

正如@iván-sánchez 建议的那样,这可能很大程度上取决于您的项目结构。您对他的回答的评论暗示了几种情况,因此最佳实践可能会有所不同。


推荐阅读