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.