[ ] Regression
[x ] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Swagger example not correct generate parameters
parameters should generate correct.
use example codes:
https://github.com/nestjs/nest/tree/master/sample/11-swagger
Nest version: 5.0.0-rc.2
{
"@nestjs/microservices": "^5.0.0-rc.2",
"@nestjs/common": "^5.0.0-rc.2",
"@nestjs/core": "^5.0.0-rc.2",
"@nestjs/passport": "^1.0.6",
"@nestjs/swagger": "^1.2.2",
"@nestjs/testing": "^5.0.0-rc.2",
"@nestjs/typeorm": "^2.0.0",
"@nestjs/websockets": "^5.0.0-rc.2",
"class-transformer": "^0.1.7",
"class-validator": "^0.7.2",
"reflect-metadata": "^0.1.12",
"rxjs": "^6.0.0",
"rxjs-compat": "^6.0.0",
"typescript": "^2.8.0"
}
For Tooling issues:
- Node version: XX
- Platform:
Others:
After spent a whole day to trace, I found the issue caused by .
https://github.com/nestjs/nest/blob/master/packages/common/decorators/http/route-params.decorator.ts
const createRouteParamDecorator = (paramtype: RouteParamtypes) => {
return (data?: ParamData): ParameterDecorator => (target, key, index) => {
const args =
Reflect.getMetadata(ROUTE_ARGS_METADATA, target.constructor, key) || {};
Reflect.defineMetadata(
ROUTE_ARGS_METADATA,
assignMetadata(args, paramtype, index, data),
target.constructor,
key,
);
};
};
const createPipesRouteParamDecorator = (paramtype: RouteParamtypes) => (
data?,
...pipes: (Type<PipeTransform> | PipeTransform)[],
): ParameterDecorator => (target, key, index) => {
const args =
Reflect.getMetadata(ROUTE_ARGS_METADATA, target.constructor, key) || {};
const hasParamData = isNil(data) || isString(data);
const paramData = hasParamData ? data : undefined;
const paramPipes = hasParamData ? pipes : [data, ...pipes];
Reflect.defineMetadata(
ROUTE_ARGS_METADATA,
assignMetadata(args, paramtype, index, paramData, ...paramPipes),
target.constructor,
key,
);
};
the target changed to target.constructor
But I do not clearly understand why need this changes?
Thanks for reporting @vellengs. I'll take care of it soon.
The compatible version of the @nestjs/swagger
has been published (v2.0.0
).
@vellengs @kamilmysliwiec I also found that in Get(':id')
, Put(':id')
, Delete(':id')
methods that id parameter does not exist in the swagger API.
in the swagger document, the API looks like /cat/{id}
, which I suppose there will be an id
parameter which is not.
@chj-damon you have to explicitly use @Param('id')
in your code.
@kamilmysliwiec Thanks, but it's not @Param('id')
, it actually is @ApiImplicitParam({ name: 'id' })
.
Not exactly. If you don't use @Param('id')
in your method signature, you have to use @ApiImplicitParam({ name: 'id' })
. Otherwise, just @Param('id')
should be enough.
@kamilmysliwiec I hardly think so.
way 1:
@Get(':id')
@Param('id')
async findById(@Param() params, @Res() res) {
const questionnaire = await this.service.findById(params.id);
return httpResult(res, true, '闂嵎鏌ヨ鎴愬姛', questionnaire);
}
it reports an error:(node:33063) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): TypeError: Cannot destructure property
prototypeof 'undefined' or 'null'.
way 2:
@Get(':id')
async findById(@Param('id') params, @Res() res) {
const questionnaire = await this.service.findById(params.id);
return httpResult(res, true, '闂嵎鏌ヨ鎴愬姛', questionnaire);
}
in swagger, there's no 'id' paramter
way 3:
@Get(':id')
@ApiImplicitParam({ name: 'id' })
async findById(@Param() params, @Res() res) {
const questionnaire = await this.service.findById(params.id);
return httpResult(res, true, '闂嵎鏌ヨ鎴愬姛', questionnaire);
}
in swagger, it works.
@kamilmysliwiec I also have to specify ApiImplicitParam otherwise the params do not show up in the UI:
@Get(':id/:id2')
@ApiImplicitParam({ name: 'id2' })
@ApiImplicitParam({ name: 'id' })
findOne(@Param('id') id, @Param('id2') id2) {
return `This action returns a #${id} cat #${id2}`;
}
Is this expected? In addition, I installed nest (CLI) from scratch today and got these versions:
[System Information]
OS Version : macOS High Sierra
NodeJS Version : v8.12.0
NPM Version : 6.4.1
[Nest Information]
swagger version : 2.5.1
common version : 5.1.0
core version : 5.1.0
Isn't 5.4.0 the latest Nest version?
Hi @kamilmysliwiec
@Get(':id')
@ApiImplicitParam({ name: 'id' })
public findById(@Param('id') id) {
return `${id}`;
}
UnhandledPromiseRejectionWarning: TypeError: Cannot read property '0' of undefined
at lodash_1.mapValues.param (@nestjs/swagger/dist/explorers/api-parameters.explorer.js:33:20)
[System Information]
OS Version : macOS High Sierra
NodeJS Version : v8.15.0
[Nest Information]
swagger version : 2.5.1
common version : 5.1.0
core version : 5.1.0
Could you please, help me
@kamilmysliwiec @vellengs Not sure why this is happening, but from my investigation, you can fix this by adding a type of string
to that function argument. for example:
@Get('/raw/:username')
getUser(@Param('username') username): string {
return 'given user: ' + username;
}
@Get('/raw/:username')
getUser(@Param('username') username: string): string {
return 'given user: ' + username;
}
the only difference is in this part: @Param('username') username: string
where I set the username parameter to be a string.
Since most of the examples here didn't include types for the function arguments, I thought I might share this because this might solve the problem in the meanwhile for people.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Most helpful comment
@kamilmysliwiec I also have to specify ApiImplicitParam otherwise the params do not show up in the UI:
Is this expected? In addition, I installed nest (CLI) from scratch today and got these versions:
Isn't 5.4.0 the latest Nest version?