首页 > 解决方案 > NestJs - 如何修改拦截器

问题描述

我的 NestJS 控制器有以下 JSON 响应:

{
   "data": [{ ... users ... }]
}

为了实现这个“包络”的东西,我使用了拦截器:

import {
    Injectable,
    NestInterceptor,
    ExecutionContext,
    CallHandler,
} from '@nestjs/common'
import { Observable } from 'rxjs'
import { map } from 'rxjs/operators'
import { plainToClass } from 'class-transformer'
import { ResponseObjectInterface } from './response-object.interface'

interface ClassType<T> {
    new (): T
}

@Injectable()
export class TransformInterceptor<T>
    implements NestInterceptor<Partial<T>, ResponseObjectInterface<T> | T> {
    constructor(
        private readonly classType: ClassType<T>,
        private readonly envelope = true
    ) {}

    intercept(
        context: ExecutionContext,
        next: CallHandler
    ): Observable<ResponseObjectInterface<T> | T> {
        return next
            .handle()
            .pipe(
                map(data =>
                    this.envelope
                        ? { data: plainToClass(this.classType, data) }
                        : plainToClass(this.classType, data)
                )
            )
    }
}

它按预期工作。现在我必须更改它并在响应中添加另一个根属性。这个:

{
   "data": { ... user ... },
   "_signed": "jwt" --> String or NULL
}

我还有其他对象(产品、订阅...等)。它们都具有相同的 JSON 签名。但他们将在_signed 中有NULL。它将是空的。只有用户签名。

我认为拦截器中有一些逻辑可以添加属性,但我不知道该怎么做。实现此功能的最佳方法是什么?

标签: node.jsnestjs

解决方案


我设法在不使用 Interceptor 的情况下解决了我的问题。

我使用了两个 DTO 对象的概念。一种是通用的,另一种是普通的。

To make story short:
import { IsNumber, IsString } from 'class-validator';
import { Exclude, Expose } from 'class-transformer';
import { ApiProperty } from '@nestjs/swagger';

@Exclude()
export class GenericResponse {
    constructor(data) {
        this.data = data
    }
    @Expose()
    @IsNumber()
    @ApiProperty()
    data: any
    public getData() {
        return this.data
    }

    @Expose()
    @IsString()
    @ApiProperty()
    private _sign: string;
    public setSignedPayload(signedPayload: string) {
        this._sign = signedPayload
    }
    public getSignedPayload() {
        return this._sign
    }
}

当我登陆 userService 时,我设置了数据,还设置了 jwt。如果我在其他地方结束,我可以选择是否设置 jwt。


推荐阅读