NestJS — Как изменить перехватчик

#node.js #nestjs

#node.js #nestjs

Вопрос:

У меня есть следующий JSON-ответ от моего контроллера NestJS:

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

Для достижения этой цели «envelope» я использую перехватчик:

 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. Но они будут иметь значение NULL в _signed. Он будет пустым. Подписан только пользователь.

Я думал, что в перехватчике должна быть какая-то логика, которая добавит свойство, но я не уверен, как это сделать. Какой был бы наилучший способ достижения этой функциональности?

Комментарии:

1. Вы сомневаетесь в том, как получить jwt? если это так, вы получаете доступ к запросу из контекста выполнения, например context.switchToHttp().запрос.заголовки.авторизация

2. Нет. Я создаю jwt. Мой вопрос касается только конструкции полезной нагрузки.

Ответ №1:

Мне удалось решить мою проблему без использования 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 или нет.