Как включить Swagger для интерфейсов API, совместно используемых NestJS и Angular в Nx monorepo?

Я хотел бы включить Swagger для интерфейсов API, совместно используемых NestJS и приложением Angular в монорепозитории Nx. Есть ли последовательный и непонятный способ?

Вот подходы, с которыми мне не удалось:

Подход 1. Примените @nestjs/swagger декораторы к общим классам DTO.

  • создать новое монорепозиторий Nx с npx create-nx-workspace@latest
  • выберите чертеж рабочего пространства angular-nest
  • установите зависимости Swagger и загрузите его в соответствии с руководством
  • добавить ввод типа Message в app.component.ts (не имеет смысла, просто для тестирования):
export class AppComponent {
  @Input() message: Message;

  hello$ = this.http.get<Message>('/api/hello');
  constructor(private http: HttpClient) {}
}
  • украсить свойство message с помощью ApiProperty() в api-interfaces.ts:
import { ApiProperty } from '@nestjs/swagger';

export class Message {
  @ApiProperty()
  message: string;
}
  • запустите приложение NestJS. Он отлично работает, Swagger отображает правильную структуру DTO в веб-представлении
  • однако, когда я запускаю приложение Angular, я получаю ошибки:
WARNING in ./node_modules/@nestjs/common/utils/load-package.util.js 8:39-59
Critical dependency: the request of a dependency is an expression

WARNING in ./node_modules/express/lib/view.js 81:13-25
Critical dependency: the request of a dependency is an expression

WARNING in ./node_modules/@nestjs/mapped-types/dist/type-helpers.utils.js
Module not found: Error: Can't resolve 'class-transformer' in '.\node_modules\@nestjs\mapped-types\dist'

ERROR in ./node_modules/@nestjs/common/cache/cache.providers.js
Module not found: Error: Can't resolve 'cache-manager' in '.\node_modules\@nestjs\common\cache'
ERROR in ./node_modules/@nestjs/common/pipes/validation.pipe.js
Module not found: Error: Can't resolve 'class-transformer' in '.\node_modules\@nestjs\common\pipes'
...

Это похоже на проблему объединения, аналогичную этой. Я не нашел элегантного рабочего решения, чтобы исправить это в сборке Angular.

Подход 2. Используйте плагин NestJS Swagger и избегайте декораторов.

Это был бы даже лучший способ, чем предыдущий, но он не работал. Во-первых, для плагина Swagger требуется NestJS CLI, чего нет в Nx monorepo. Есть проблема, предлагающая некоторые обходные пути, но я не нашел их достаточно надежными и полный. Во-вторых, плагин не охватывает некоторые важные варианты использования, для которых в любом случае требуются декораторы. Например:

@ApiProperty({
  oneOf: [{ $ref: getSchemaPath(TypeA) }, { $ref: getSchemaPath(TypeB) }],
})
type: TypeA | TypeB;

И как описано выше, декораторы приводят к ошибкам.

Подход 3. Создание интерфейсов из классов DTO для специального использования в приложении Angular.

Что меня привлекает в этом подходе, так это возможность абстрагироваться от специфической логики серверной части, будь то декораторы Swagger, сериализация или валидация. Мы могли сделать следующее:

// Expose to the back-end
export class MessageDto {
  @ApiProperty()
  message: string;
}

// Expose to the front-end
export interface Message extends MessageDto {}

В этом случае интерфейс Message хорошо компилируется с приложением Angular. Но как только мы вводим более сложные композиции DTO (классы с вложенными DTO), этот подход не работает.

Буду признателен за любые другие идеи.


person Andriy Chuma    schedule 11.05.2020    source источник
comment
Это может быть полный обходной путь (он же не решение), если вы включите Swagger на стороне NestJS, тогда вы, возможно, захотите вместо совместного использования интерфейсов использовать сторонний инструмент для создания заглушек API для стороны Angular с помощью таких инструментов, как : nswag, swagger-codegen, ng-openapi-gen и т. д. Эти инструменты принимают файл swagger.json в качестве входных данных.   -  person Chau Tran    schedule 11.05.2020
comment
Спасибо, @ChauTran! Это хороший способ, если мне не удастся заставить его работать с вышеупомянутым стеком. Я углублюсь в инструменты и возможности их автоматизации.   -  person Andriy Chuma    schedule 12.05.2020


Ответы (2)


Мне удалось разделить DTO (ы) между Angular и Nest.js (подход № 1)

Замена @angular-devkit/build-angular:browser на @angular-builders/custom-webpack:browser устранила ошибки при создании или обслуживании приложения angular.

См. https://github.com/nestjs/nest/issues/1706#issuecomment-474657479 для получения дополнительных сведений.

person ngson2000    schedule 10.08.2020

В качестве простого обходного пути вы можете использовать декоратор ApiModelProperty вместо ApiProperty:

import { ApiModelProperty } from '@nestjs/swagger/dist/decorators/api-model-property.decorator';

ApiModelProperty не вызывает проблем с внедрением кеш-менеджера, а декоратор позволит вам настроить документацию API для DTO.

person Dmitrii Borisenko    schedule 27.10.2020