乐闻世界logo
搜索文章和话题

如何使用 NestJs @ Body 解析 JSON 请求中的日期

8 个月前提问
6 个月前修改
浏览次数67

1个答案

1

在 NestJS 中,@Body() 装饰器用于提取请求的主体数据。默认情况下,NestJS 使用 Express 或 Fastify 作为 HTTP 服务器,它们已经配置了一个内置的中间件来解析 JSON 请求体。

当接受 JSON 请求并期望请求体中包含日期字段时,这些日期字段通常会被解析为字符串。为了将这些字符串转换为 JavaScript Date 对象,我们有几种方法可以实现。

使用管道进行转换

NestJS 的管道(Pipe)功能可以在数据到达控制器处理程序之前转换和验证数据。我们可以创建一个自定义管道来解析并验证日期字符串。

例如,假设我们有一个请求体,它包含一个 startDate 字段:

json
{ "startDate": "2023-04-01" }

我们可以创建一个 ParseDatePipe,如下所示:

typescript
import { PipeTransform, Injectable, BadRequestException } from '@nestjs/common'; @Injectable() export class ParseDatePipe implements PipeTransform { transform(value: any): Date { // 确保传入的值是字符串并且可以被解析成日期 if (typeof value === 'string' && !isNaN(Date.parse(value))) { return new Date(value); } else { throw new BadRequestException('Invalid date format'); } } }

然后,在控制器中,我们可以将这个管道应用到具体的请求体字段上:

typescript
import { Controller, Post, Body } from '@nestjs/common'; import { ParseDatePipe } from './parse-date.pipe'; @Controller('events') export class EventsController { @Post() createEvent( // 应用 ParseDatePipe 到 startDate 字段上 @Body('startDate', ParseDatePipe) startDate: Date ) { // startDate 现在是一个 JavaScript Date 对象 // 在这里可以进行进一步的逻辑处理 } }

使用类校验器和转换器

在更复杂的情况下,或者当我们想要在整个应用程序中一致地处理日期时,我们可以使用类校验器(如 class-validator)和类转换器(如 class-transformer)。这些库可以很好地与 NestJS 集成,为请求体提供更强大的校验和转换功能。

首先,确保安装了所需的包:

sh
npm install class-validator class-transformer

然后,定义一个 DTO(数据传输对象)并使用装饰器来声明如何自动转换和校验字段:

typescript
import { IsDateString, IsNotEmpty } from 'class-validator'; import { Type } from 'class-transformer'; export class CreateEventDto { @IsNotEmpty() @IsDateString() readonly name: string; @Type(() => Date) // 使用 class-transformer 来转换字段为 Date @IsDateString() readonly startDate: Date; }

在控制器中,使用 @Body() 装饰器来应用这个 DTO:

typescript
import { Controller, Post, Body } from '@nestjs/common'; import { CreateEventDto } from './create-event.dto'; @Controller('events') export class EventsController { @Post() createEvent(@Body() createEventDto: CreateEventDto) { // createEventDto.startDate 现在是一个 JavaScript Date 对象 // 可以继续处理业务逻辑 } }

记得在主 app.module.ts 中启用全局管道,这样可以自动应用转换和校验逻辑:

typescript
import { Module } from '@nestjs/common'; import { APP_PIPE } from '@nestjs/core'; import { ValidationPipe } from '@nestjs/common'; @Module({ // ... providers: [ { provide: APP_PIPE, useClass: ValidationPipe, // 启用全局校验管道 }, ], }) export class AppModule {}

使用 class-validatorclass-transformer 能够让你的应用程序以声明式的方式处理日期字段的转换和校验,这在构建具有多个日期字段或者需要复杂校验逻辑的应用程序时非常有用。

2024年6月29日 12:07 回复

你的答案