简体   繁体   中英

NestJs - How to modify interceptor

I have following JSON response from my NestJS Controller:

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

To achieve this "envelop" thing, I use the interceptor:

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)
                )
            )
    }
}

It works as expected. Now I have to change it and add another root property on the response. This:

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

I have other objects (products, subscriptions...etc). All of them have the same JSON signature. But they will have NULL in the _signed. It will be empty. Only user is signed.

I thought to have some logic in the the interceptor that will add the property, but I am not sure how to do it. What would be the best way of achieving this functionality?

I managed to resolve my issue without using Interceptor whatsoever.

I used concept of two DTO objects. One is generic, and another one is plain one.

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
    }
}

And when I land in userService, I set the Data, also I set the jwt. If I end somewhere else, I can choose whether to set the jwt or not.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM