未知字段
本课属于 Coddy Node.js 学习旅程的“TypeScript 和 NestJS”单元。第 16 课,共 24 课。
客户端可以发送 DTO 中未提及的字段,例如 { "title": "x", "admin": true },这些字段会原样到达你的代码。ValidationPipe 有两个选项可以处理这些字段。
app.useGlobalPipes(
new ValidationPipe({ whitelist: true }),
);whitelist: true 会在你的方法接收请求体之前,移除所有没有验证装饰器的字段。添加 forbidNonWhitelisted: true 后,管道会改为拒绝这样的请求体,并返回 400 和 "property admin should not exist"。forbidNonWhitelisted 只有与 whitelist 一起使用才有效;单独使用时不会起作用。
静默移除适合发送了额外输入的表单。拒绝请求则会让 API 客户端知道自己有拼写错误,例如 titel。
挑战
简单客户端可以发送 DTO 中从未提及的字段,例如 "owner": "admin",而现在这些字段会原封不动地到达你的代码。让 API 拒绝它们,这样客户端输入错误或偷偷添加额外字段时就会知道。
- 在
src/main.ts中,找到bootstrap已经注册的ValidationPipe。传入两个选项:whitelist: true,它会移除所有没有验证装饰器的字段;以及forbidNonWhitelisted: true,它会以 400 错误拒绝包含这类字段的请求体,而不是移除字段。第二个选项只有与第一个选项一起使用时才有效。 - 不要更改其他内容。只包含
title和done的请求体仍然有效,错误的标题仍会被拒绝。
试试看:向 /tasks 发送 POST 请求,内容为 { "title": "Book flights", "owner": "admin" }。你会收到 400 错误:
{ "message": ["property owner should not exist"], "error": "Bad Request", "statusCode": 400 }然后发送 POST 请求,内容为 { "title": "Book flights" }:返回 201,并创建新任务。{ "title": 7 } 仍会返回 400。
亲手试试
import { ValidationPipe } from '@nestjs/common';
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe());
await app.listen(3000);
}
bootstrap();
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
TypeScript 和 NestJS中的所有课
自己练习: Express 在线编辑器