Nest.js swagger - типы в dto не видны в swagger

Я настраиваю документ swagger в своем небольшом приложении Nest.js в соответствии с этой документацией: https://docs.nestjs.com/recipes/swagger

Мой вопрос: как мне настроить dto, чтобы правильно отображать схему в чванстве? Если быть более конкретным, вложенные типы. Он показывает только ключи верхнего уровня. Если один из ключей имеет тип чего-то, он показывает это как пустой объект. Вот что я имею в виду:

dto:

export class HealthCheckDataDto {
    serverStatus: {} // dont have it typed yet;
    dbStatus: MongoConnectionStateT;
} 

чванство:

[
  {
    "serverStatus": {},
    "dbStatus": {}
  }
]

ожидаемый результат в примере значения swagger:

[
  {
    "serverStatus": {},
    "dbStatus": {
      "isOnline": true,
      "msg": "string"
    }
  }
]

Это функция:

@ApiResponse({ status: 200, description: 'blabla', type: [HealthCheckDataDto] })
@ApiResponse({ status: 500, description: 'blabla, but bad', type: [HealthCheckDataDto] })
@Get('/api/healthcheck')
healthCheckApp(@Res() res: Response<HealthCheckDataDto>) {

    // check HCs and setup status code
    const healthCheck: HealthCheckI = this.healthcheckService.getFullHealthCheck();
    const statusCode = (healthCheck.dbStatus.isOnline) ? HttpStatus.OK : HttpStatus.INTERNAL_SERVER_ERROR;

    // return that response
    res.status(statusCode).json(healthCheck);
}

Что пробовал:

  • Когда я заменил type на точные параметры в dto, он правильно показывает это в swagger.
  • Я провел перекрестную проверку dto на интерфейс, где я добавил неправильное поле в isOnline, и он нашел его и пометил, что он плохой.
  • Схема отображается в виде чванства, но только на верхнем уровне, а не в типизированной части. Так что это не просто примерное значение.
  • Проверил SO:) Найдены две связанные темы, но не решены. Один из них предложил создавать подпрограммы manulaly вместо типов. Ну... лучше не надо.

Я что-то делаю не так или что-то пропустил в документации. Или, может быть, парсер этого модуля swagger не может извлечь тип / интерфейс при генерации json. Не знаю.

Любая идея, пожалуйста?

Спасибо!

3 ответа

Решение

Я пропустил одно место в документации:
https://docs.nestjs.com/recipes/swagger

Поскольку TypeScript не хранит метаданные о универсальных шаблонах или интерфейсах, когда вы используете их в своих DTO, SwaggerModule не сможет правильно генерировать определения модели во время выполнения.

Что ж, в этом есть смысл.

В некоторых конкретных сценариях (например, глубоко вложенные массивы, матрицы) вы можете описать свой тип вручную.

РЕДАКТИРОВАТЬ

Итак, последняя установка, которая работает для меня, следующая

  • Создать DTO без типов, но соответствует структуре типа / интерфейса, как и в "ожидаемом результате" в исходном вопросе
  • запрос / ответ следует набирать с dto, например Result<SomeDto>
  • когда вы обрабатываете данные в этой функции, введите их с интерфейсом / типом, а не с dto, и вы получите перекрестную проверку.

Подобно тому, как эти данные действительны, чванство генерируется правильно. Для получения дополнительной информации о чванстве используйте декораторы непосредственно в DTO.

Вы можете автоматически отображать типы в Swagger с помощью подключаемого модуля OpenAPI CLI .

Добавлять:

        "compilerOptions": {
    "plugins": ["@nestjs/swagger"]
  }

к nest-cli.json, и добавить:

      import { ApiProperty, ApiBody } from '@nestjs/swagger';

к каждому из ваших DTO, и плагин автоматически аннотирует и документирует ваши схемы!

Согласно документации из типов и параметров , вам просто нужно использовать либо

      @Body(), @Query(), @Param()

тогда модуль swagger автоматически заполнит данные для вас. это также требует, чтобы вы обновили свой nest-cli.jsonфайл в

      {
"collection": "@nestjs/schematics",
  "sourceRoot": "src",
  "compilerOptions": {
    "plugins": ["@nestjs/swagger/plugin"]
  }
}

тогда все должно быть сделано и сгенерировано для вас.

просто на заметку, если это не показывает их автоматически или не показывает, что схема пуста, тогда вы украшаете хотя бы одну запись своего dto с помощью @ApiProperty()затем обновите страницу. это улучшит дело.

Другие вопросы по тегам