nestjs / swagger

OpenAPI (Swagger) module for Nest framework (node.js) :earth_americas:
https://nestjs.com
MIT License
1.69k stars 475 forks source link

Query and Parameters are not generated when they have a default value #2328

Closed linsolas closed 1 year ago

linsolas commented 1 year ago

Is there an existing issue for this?

Current behavior

Hello,

I'm wondering if it is an intended behavior to have the query or parameter automatically generated from @Query and @Param only when a default value is not defined?

Let's take that example:

  @Get('/foo/:param1/:param2')
  public async doSomething(
    @Query('query1') query1: string,
    @Query('query2') query2 = 'bar',
    @Param('param1') param1: string,
    @Param('param2') param2 = 'here',
  ) {
    // ...
  }

When generating the Swagger file, I get the following content:

{
  "paths": {
    "/api/v1/foo/{param1}/{param2}": {
      "get": {
        "operationId": "MyController_doSomething",
        "parameters": [{
          "name": "query1",
          "required": true,
          "in": "query",
          "schema": {
            "type": "string"
          }
        }, {
          "name": "param1",
          "required": true,
          "in": "path",
          "schema": {
            "type": "string"
          }
        }],
        "responses": {
          "200": {
            "description": ""
          }
        }
      }
    }
  }
}

As you can see, only param1 and query1 elements are defined, and not param2 nor query2.

Of course, the good practice would be to set myself the @ApiParam() or the @ApiQuery() decorators.

Why is it like this? Is it because it's harder to identify the schema type of the property through introspection?

Thanks

Minimum reproduction code

none

Steps to reproduce

No response

Expected behavior

I would expect to have something like this instead:

{
  "paths": {
    "/api/v1/foo/{param1}/{param2}": {
      "get": {
        "operationId": "MyController_doSomething",
        "parameters": [{
          "name": "query1",
          "required": true,
          "in": "query",
          "schema": {
            "type": "string"
          }
        }, {
          "name": "query2",
          "required": false,
          "in": "query",
          "schema": {
            "type": "string"
          }
        }, {
          "name": "param1",
          "required": true,
          "in": "path",
          "schema": {
            "type": "string"
          }
        }, {
          "name": "param2",
          "required": false,
          "in": "path",
          "schema": {
            "type": "string"
          }
        }],
        "responses": {
          "200": {
            "description": ""
          }
        }
      }
    }
  }
}

Package version

6.1.4

NestJS version

9.2.1

Node.js version

16.17.0

In which operating systems have you tested?

Other

No response

kamilmysliwiec commented 1 year ago

Please provide a minimum reproduction repository (Git repository/StackBlitz/CodeSandbox project).

linsolas commented 1 year ago

Hello @kamilmysliwiec,

I've created this demo page: https://stackblitz.com/edit/nestjs-typescript-starter-8lt7s2?file=src/main.ts

When running this small demo, the Swagger UI shows only query1 and param1, while we also have query2 and param2 in the AppController:

image

kamilmysliwiec commented 1 year ago

It seems that Nest cannot auto-infer types of default values because TS compiler sets query2 and param2 parameter types to Object:

__metadata("design:paramtypes", [String, Object, String, Object]),

If you change the method signature to this:

@Query('query1') query1: string,
@Query('query2') query2: string = 'bar',
@Param('param1') param1: string,
@Param('param2') param2: string = 'here',

everything will work as expected

image