Как передать вложенный класс для ввода @ApiOkResponse или создать соответствующий пользовательский декоратор?

Задний план:

Я использовал перехватчик nestjs, чтобы поместить возвращаемые данные с контроллера внутрь dataсвойство и добавить некоторые другие свойства. Теперь я хочу использовать@ApiOkResponse это отражало бы вложенные свойства.

Контроллер возвращается

{
   prop1: 'val1',
   prop2:  'val2'
}

После перехвата возвращается

data: {
   prop1: 'val1',
   prop2:  'val2'
},
addedProp: 'addedVal'

У меня также есть два класса:

// Have many variations of similar classes (for different controllers (types of data)
class NotYetIntercepted {
   @ApiProperty()
   prop1: string;

   @ApiProperty()
   prop2: string;
}

class Intercepted<T = any> {
   @ApiProperty()
   data: T;

   @ApiProperty()
   addedProp: string;
}

Вызов

Теперь я хочу добавить в свои контроллеры @ApiOkResponse({ type: Intercepted }) но также как-то указать, что data собственность класса Intercepted должен быть типа NotYetIntercepted.

Я пробовал создать собственный декоратор следующим образом:

import { ValidateNested } from 'class-validator';
import { ApiProperty, ApiResponseOptions, ApiOkResponse } from '@nestjs/swagger';
import { Intercepted } from '@appnamespace/models';
import { Type } from 'class-transformer';

export const CustomApiOkResponse = (notYetIntercepted: Function, options?: Omit<ApiResponseOptions, 'type'>) => {

  class InterceptedWithData extends Intercepted {

    @ApiProperty()
    @ValidateNested()
    @Type(() => notYetIntercepted)
    data: typeof notYetIntercepted;
  }

  return ApiOkResponse({
    ...options,
    type: InterceptedWithData,
  });
};

Это не сработало. Когда я удалил@Type() => notYetIntercepted) и установить data как data: notYetIntercepted он вроде как работал (с предупреждением машинописного текста), но он переопределял все значения в моих документах swagger на то, что было последним переданным значением в (@CustomApiOkResponse(AnotherNotYetIntercepted)).

Я знаю, что могу создать класс для каждого вложенного типа данных, но есть ли более чистое решение?

Спасибо за ваше время

2 ответа

У меня были некоторые проблемы с циклическими зависимостями, когда я пытался установить тип на@ApiOkResponse, и моя проблема была решена путем удаления всехnullзначения свойств в . Гнездо отклоняет нуль как тип.DTO.

Один из вариантов - динамическая передача схемы Swagger с помощью вашего настраиваемого декоратора. В nestjs/terminus было сделано нечто очень похожее - см. health-check.decorator.ts а также health-check.schema.ts.

Вкратце, вы можете передавать пользовательские определения через schema вариант.

export const CustomApiOkResponse = (notYetIntercepted: Function, options?: Omit<ApiResponseOptions, 'type'>) => {
  return ApiOkResponse({
    ...options,
    schema: {
     // .. your Swagger Schema
    }
  });
};
Другие вопросы по тегам