gpt4 book ai didi

nest - 使用自定义拦截器进行响应

转载 作者:行者123 更新时间:2023-12-05 04:33:45 30 4
gpt4 key购买 nike

我正在使用全局拦截器来获取如下响应:

{
"data": "",
"statusCode": int
"message": "string"
}

所以我创建了拦截器文件

import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from "@nestjs/common";
import { map, Observable } from "rxjs";

export interface Response<T> {
data: T;
}

@Injectable()
export class TransformationInterceptor<T> implements NestInterceptor<T, Response<T>> {
intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
return next.handle().pipe(map(data => ({
data: data,
statusCode: context.switchToHttp().getResponse().statusCode,
message: data.message
})));
}
}

并将其放入我的main.ts

在我的 Controller 中我有:

  @Patch('/:userId')
@HttpCode(201)
public async updateUser(
@Param('userId') userId: string,
@Body() userUpdate: UpdateUserDto): Promise<any> {
return await this.usersService.update(userId, userUpdate);
}

结果是:

{
"data": {
"_id": "621d07d9ea0cdc600fae0f02",
"username": "foo",
"name": "stringwwww",
"__v": 0
},
"statusCode": 201
}

如果我想添加我的自定义消息,我需要返回一个像这样的对象:

@Patch('/:userId')
@HttpCode(201)
public async updateUser(
@Param('userId') userId: string,
@Body() userUpdate: UpdateUserDto): Promise<any> {
const result = await this.usersService.update(userId, userUpdate);
return { message: 'User updated', result };
}

但在那种情况下我有两次消息并且结构不正确:

{
"data": {
"message": "User updated",
"result": {
"_id": "621d07d9ea0cdc600fae0f02",
"username": "foo",
"name": "stringwwww",
"__v": 0
}
},
"statusCode": 201,
"message": "User updated"
}

如何设置自定义(可选)消息?

I can modify my interceptors like:
@Injectable()
export class TransformationInterceptor<T> implements NestInterceptor<T, Response<T>> {
intercept(context: ExecutionContext, next: CallHandler): Observable<Response<T>> {
return next.handle().pipe(map(data => ({
data: data.res,
statusCode: context.switchToHttp().getResponse().statusCode,
message: data.message
})));
}
}

我的 Controller 是这样的:

@Patch('/:userId')
@HttpCode(201)
public async updateUser(
@Param('userId') userId: string,
@Body() userUpdate: UpdateUserDto): Promise<any> {
const result = await this.usersService.update(userId, userUpdate);
return { message: 'User updated', res: result };
}

我会得到正确的表格,但我不想添加

return { message: 'User updated', res: result };    

对于每个 Controller

最佳答案

实现此目的的一种方法如下,但您将被绑定(bind)到每个 Controller 的固定消息

创建一个响应装饰器(response.decorator.ts)

import { SetMetadata } from '@nestjs/common'

export const ResponseMessageKey = 'ResponseMessageKey'
export const ResponseMessage = (message: string) => SetMetadata(ResponseMessageKey, message)

为您的响应创建常量文件 (response.constants.ts)

export const USER_INSERTED = 'User Inserted'
export const USER_UPDATED = 'User Updated'
export const USER_DELETED = 'User Deleted'

将装饰器添加到您的 Controller 以设置响应消息元数据

@Patch('/:userId')
@HttpCode(201)
@ResponseMessage(USER_UPDATED)
public async updateUser(
@Param('userId') userId: string,
@Body() userUpdate: UpdateUserDto
): Promise<any> {
const result = await this.usersService.update(userId, userUpdate);
return result;
}

更新您的拦截器以从 Controller 上设置的元数据中读取响应消息并将其添加到响应中

import { Reflector } from '@nestjs/core'

@Injectable()
export class TransformationInterceptor<T>
implements NestInterceptor<T, Response<T>>
{
constructor(private reflector: Reflector) {}

intercept(
context: ExecutionContext,
next: CallHandler
): Observable<Response<T>> {
const responseMessage = this.reflector.get<string>(
ResponseMessageKey,
context.getHandler()
) ?? ''

return next.handle().pipe(
map((data) => ({
data,
statusCode: context.switchToHttp().getResponse().statusCode,
message: responseMessage
}))
)
}
}

您可以扩展此方法以将字符串/对象列表设置为可能的响应(元数据),并根据拦截器中的响应代码,将特定消息发送为 response.message

关于nest - 使用自定义拦截器进行响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71342465/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com