admin管理员组

文章数量:1180493

I'm setting up swagger document in my small Nest.js app according to this documentation:

How do I setup dto to correctly show schema in swagger? To be more specific, nested types. It shows only top level keys. If one of the keys is of type of something, it shows it just as empty object. Here is what I mean:

dto:

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

swagger:

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

expected result in swagger example value:

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

This is the function:

@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);
}

What I tried:

  • When I replaced type for exact params in dto, it shows it properly in swagger.
  • I did cross-check of dto against interface, where I added wrong field into 'isOnline' and it finds it and marks it, that it isnt good.
  • Schema is displayed in swagger, but also only top level, not the typed part. So its not just example value.
  • Checked Stack Overflow; found two related threads, but neither one solved it. One suggested to manually create sub-dtos instead of types. Well... I better not do that.

I'm doing something wrong, or missed something in documentation. Or maybe parser of that swagger module is unable to extract type/interface when generating json.

I'm setting up swagger document in my small Nest.js app according to this documentation: https://docs.nestjs.com/recipes/swagger

How do I setup dto to correctly show schema in swagger? To be more specific, nested types. It shows only top level keys. If one of the keys is of type of something, it shows it just as empty object. Here is what I mean:

dto:

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

swagger:

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

expected result in swagger example value:

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

This is the function:

@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);
}

What I tried:

  • When I replaced type for exact params in dto, it shows it properly in swagger.
  • I did cross-check of dto against interface, where I added wrong field into 'isOnline' and it finds it and marks it, that it isnt good.
  • Schema is displayed in swagger, but also only top level, not the typed part. So its not just example value.
  • Checked Stack Overflow; found two related threads, but neither one solved it. One suggested to manually create sub-dtos instead of types. Well... I better not do that.

I'm doing something wrong, or missed something in documentation. Or maybe parser of that swagger module is unable to extract type/interface when generating json.

Share Improve this question edited Jul 15, 2021 at 18:02 TylerH 21.1k77 gold badges79 silver badges111 bronze badges asked Mar 31, 2020 at 14:46 PeterPeter 3711 gold badge4 silver badges10 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 14

You can show types in Swagger automatically using the OpenAPI CLI plugin.

Add:

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

to nest-cli.json, and add:

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

to each of your DTOs, and the plugin will automagically annotate and document your schemas!

I missed one spot in NestJS Documentation: Generics and interfaces:

Since TypeScript does not store metadata about generics or interfaces, when you use them in your DTOs, SwaggerModule may not be able to properly generate model definitions at runtime.

Well, it makes sense.

In some specific scenarios (e.g. deeply nested arrays, matrices), you may want to describe your type by hand.

So, the final setup that works for me is following

  • Create DTO without types, but matches type/interface structure just like in 'expected result' in the original question
  • request/response should be typed with dto, eg Result<SomeDto>
  • when you handle data in that function, type it with interface/type, not dto and you have crosscheck.

Like this data are valid, swagger is properly generated. For additional swagger informations, use decorators directly in DTO.

According to the documentation from types and parameters you just have to use either

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

then the swagger module will automatically populate things for you. this also requires that you update your nest-cli.json file to

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

then all things should be done and generated for you.

just a heads up,if this doesn't automatically show them or show the schema to be empty, then you deocorate at least one entry of your dto with @ApiProperty() then refresh the page. this will get things done.

本文标签: javascriptWhy are types in dto not visible in swaggerStack Overflow