跳转到内容

响应转换

ResponseInterceptor 自动将控制器返回的数据包装为统一的响应格式。

模块注册

typescript
import { TransformModule } from '@maxtan/nest-core'

@Module({
  imports: [
    TransformModule.forRoot({
      transformDate: true,       // 自动将 Date 转为时间戳(默认 true)
      normalizeHttpCode: true,   // 自动将 201 状态码转为 200(默认 true)
      // formatter: (data) => ({ status: 'ok', result: data })  // 自定义格式
    })
  ]
})
export class AppModule {}

配置选项

选项类型默认值说明
enabledbooleantrue是否启用
globalbooleantrue是否全局注册
transformDatebooleantrue是否将 Date/ISO 字符串转时间戳
normalizeHttpCodebooleantrue是否将 POST/PUT/PATCH 的 201 状态码统一为 200
formatterfunction-自定义响应格式化函数

统一响应格式

typescript
// 控制器直接返回数据
return { id: 1, name: 'John' }

// 拦截器自动转换为
{
  "code": 200,
  "data": { "id": 1, "name": "John" },
  "message": "成功",
  "timestamp": 1700000000000
}

响应类型定义

typescript
interface Res<T = any> {
  code: number
  data: T
  message: string
  timestamp: number
}

自定义消息

默认消息为「成功」,需要自定义时使用 resMessage()

typescript
import { resMessage } from '@maxtan/nest-core'

@Post()
async create(@Body(Zod(CreateUser)) dto: CreateUser) {
  const user = await this.userService.create(dto)
  return resMessage(user, '创建成功')    // → { code: 200, data: user, message: '创建成功', ... }
}

@Delete(':id')
async delete(@Param('id') id: string) {
  await this.userService.delete(id)
  return resMessage({ id }, '删除成功')  // → { code: 200, data: { id }, message: '删除成功', ... }
}

@Get()
async list(@Query(Zod(ListUser)) query: ListUser) {
  return this.userService.list(query)    // → { code: 200, data: [...], message: '成功', ... }
}

只返回数据 → 拦截器自动包装,message 为「成功」
resMessage(data, msg) → 拦截器自动包装,message 为自定义值

Date 自动转换

默认自动将 Date 对象和 ISO 8601 日期字符串转为毫秒时间戳:

typescript
// 控制器返回
return {
  name: 'John',
  createdAt: new Date('2025-01-01T00:00:00Z'),
  loginTime: '2025-06-15T12:00:00Z'
}

// 转换后
{
  "data": {
    "name": "John",
    "createdAt": 1735689600000,
    "loginTime": 1750075200000
  }
}

设置 transformDate: false 可禁用此行为。

跳过转换的场景

以下场景不会进行响应格式转换:

  • 响应已发送(reply.sent
  • StreamableFile 返回
  • 非 JSON Content-Type(text/plainimage/*application/octet-stream 等)
  • BufferStream 返回
  • 已经是标准响应格式(包含 codetimestamp

自定义格式

typescript
TransformModule.forRoot({
  formatter: (data) => ({
    status: 'ok',
    result: data,
    time: Date.now()
  })
})

工具函数

typescript
import { resMessage } from '@maxtan/nest-core'

// 携带自定义消息(推荐)
return resMessage(user, '创建成功')

// 无需自定义消息时,直接返回数据即可
return user

getSuccessRes() / successRes() 已标记 @deprecated,新代码请直接返回数据或使用 resMessage()

最佳实践

  1. 直接返回数据:大多数接口直接 return data 即可,拦截器自动包装
  2. CUD 操作加消息:创建 / 更新 / 删除用 resMessage(data, '操作成功') 提示用户
  3. 不要手动包装响应:避免 return { code: 200, data, message: '成功' },拦截器自动处理
  4. Date 转换用默认值:保持 transformDate: true,确保前后端时间格式一致

相关文档