Как передать вложенный класс для ввода @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
}
});
};