外观
响应转换
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 {}配置选项
| 选项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
enabled | boolean | true | 是否启用 |
global | boolean | true | 是否全局注册 |
transformDate | boolean | true | 是否将 Date/ISO 字符串转时间戳 |
normalizeHttpCode | boolean | true | 是否将 POST/PUT/PATCH 的 201 状态码统一为 200 |
formatter | function | - | 自定义响应格式化函数 |
统一响应格式
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/plain、image/*、application/octet-stream等) Buffer或Stream返回- 已经是标准响应格式(包含
code、timestamp)
自定义格式
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()。
最佳实践
- 直接返回数据:大多数接口直接
return data即可,拦截器自动包装 - CUD 操作加消息:创建 / 更新 / 删除用
resMessage(data, '操作成功')提示用户 - 不要手动包装响应:避免
return { code: 200, data, message: '成功' },拦截器自动处理 - Date 转换用默认值:保持
transformDate: true,确保前后端时间格式一致