英文:
NestJS: Custom decorator `applyDecorators()` not working with `HttpCode` and `AuthGuard` used together
问题
场景:
我已经创建了两个自定义装饰器,以简化我的控制器,通过在一个地方应用所有常见的Swagger装饰器。它们如下所示。
export function AuthorizedEndpoint(header_key?: string) {
return applyDecorators(
// HttpCode(200), // @Todo Why is it not working?
UseGuards(AuthGuard),
ApiBearerAuth(header_key),
ApiOkResponse({ description: ResponseMessageEnum.R_SUCCESS as string }),
ApiUnprocessableEntityResponse({ description: ResponseMessageEnum.R_BAD_REQUEST as string }),
ApiForbiddenResponse({ description: ResponseMessageEnum.R_UNAUTHORIZED as string }),
ApiNotFoundResponse({ description: ResponseMessageEnum.R_NOT_FOUND as string })
);
}
export function OpenAccessEndpoint() {
return applyDecorators(
HttpCode(200),
ApiOkResponse({ description: ResponseMessageEnum.R_SUCCESS as string }),
ApiUnprocessableEntityResponse({ description: ResponseMessageEnum.R_BAD_REQUEST as string }),
ApiForbiddenResponse({ description: ResponseMessageEnum.R_UNAUTHORIZED as string }),
ApiNotFoundResponse({ description: ResponseMessageEnum.R_NOT_FOUND as string })
);
我的所有控制器都是POST,nestjs发送201作为响应代码。但我想发送200。因此,我使用@HttpCode(200)
来发送所需的响应代码。当直接在控制器上使用时,它起作用。
问题:
在不实现AuthGuard
的自定义装饰器中,HttpCode
装饰器按预期工作,但在Authorized
装饰器中,如果我使用@HttpCode
装饰器,会出现以下消息。如果我将其注释掉,它将按预期工作并发送201默认响应。
[11:30:25 AM] File change detected. Starting incremental compilation...
[11:30:25 AM] Found 0 errors. Watching for file changes.
C:\Users\Lenovo\Project\node_modules\reflect-metadata\Reflect.js:541;
var decorated = decorator(target);
^
TypeError: Cannot read properties of undefined(reading 'value')
at C:\Users\Lenovo\Project\node_modules\@nestjs/common/decorators/http/http-code.decorator.js:17:87
at C:\Users\Lenovo\Project\node_modules\@nestjs/common/decorators/core/apply-decorators.js:17:17
at DecorateConstructor(C:\Users\Lenovo\Project\node_modules\reflect-metadata\Reflect.js:541:33)
at Reflect.decorate(C:\Users\Lenovo\Project\node_modules\reflect-metadata\Reflect.js:130:24)
at __decorate(C:\Users\Lenovo\Project\dist\administration\controllers\organization.controller.js:4:92)
at Object.<anonymous>(C:\Users\Lenovo\Project\src\administration\controllers\organization.controller.ts:14:37)
at Module._compile(node:internal/modules/cjs/loader:1239:14)
at Object.Module._extensions..js(node:internal/modules/cjs/loader:1293:10)
at Module.load(node:internal/modules/cjs/loader:1096:32)
at Function.Module._load(node:internal/modules/cjs/loader:935:12);
问题:
这是一个bug,还是我配置错误?上面错误消息的解释是什么?我该如何继续?
英文:
Scenerio:
I have created two custom decorators as a way to cleanup my controllers by applying all the common swagger decorators, at one place. They are as following.
export function AuthorizedEndpoint(header_key?: string) {
return applyDecorators(
// HttpCode(200), // @Todo Why is it not working?
UseGuards(AuthGuard),
ApiBearerAuth(header_key),
ApiOkResponse({ description: ResponseMessageEnum.R_SUCCESS as string }),
ApiUnprocessableEntityResponse({ description: ResponseMessageEnum.R_BAD_REQUEST as string }),
ApiForbiddenResponse({ description: ResponseMessageEnum.R_UNAUTHORIZED as string }),
ApiNotFoundResponse({ description: ResponseMessageEnum.R_NOT_FOUND as string })
);
}
export function OpenAccessEndpoint() {
return applyDecorators(
HttpCode(200),
ApiOkResponse({ description: ResponseMessageEnum.R_SUCCESS as string }),
ApiUnprocessableEntityResponse({ description: ResponseMessageEnum.R_BAD_REQUEST as string }),
ApiForbiddenResponse({ description: ResponseMessageEnum.R_UNAUTHORIZED as string }),
ApiNotFoundResponse({ description: ResponseMessageEnum.R_NOT_FOUND as string })
);
All my controllers are POST, and nestjs sends 201 as response code. But I want to send 200 instead. Therefore, I used the @HttpCode(200)
to send required response code. It is working when using on controllers directly.
ISSUE:
In the custom decorator, which does not implement AuthGuard
, HttpCode decorator is working as expected, but in the Authorized Decorator, If I use @HttpCode
decorator, I get the following message. If I comment it out, it works as expected and sends 201 default response.
[11:30:25 AM] File change detected. Starting incremental compilation...
[11:30:25 AM] Found 0 errors. Watching for file changes.
C: \Users\Lenovo\Project\node_modules\reflect - metadata\Reflect.js: 541;
var decorated = decorator(target);
^
TypeError: Cannot read properties of undefined(reading 'value')
at C: \Users\Lenovo\Project\node_modules\@nestjs\common\decorators\http\http - code.decorator.js: 17: 87
at C: \Users\Lenovo\Project\node_modules\@nestjs\common\decorators\core\apply - decorators.js: 17: 17
at DecorateConstructor(C: \Users\Lenovo\Project\node_modules\reflect - metadata\Reflect.js: 541: 33)
at Reflect.decorate(C: \Users\Lenovo\Project\node_modules\reflect - metadata\Reflect.js: 130: 24)
at __decorate(C: \Users\Lenovo\Project\dist\administration\controllers\organization.controller.js: 4: 92)
at Object.<anonymous>(C: \Users\Lenovo\Project\src\administration\controllers\organization.controller.ts: 14: 37)
at Module._compile(node: internal / modules / cjs / loader: 1239: 14)
at Object.Module._extensions..js(node: internal / modules / cjs / loader: 1293: 10)
at Module.load(node: internal / modules / cjs / loader: 1096: 32)
at Function.Module._load(node: internal / modules / cjs / loader: 935: 12);
Question:
Is this a bug, or some misconfiguration from my end? What is the explaination of above error message? How do I move ahead from it?
答案1
得分: 0
"@HttpCode()
" 是一个方法装饰器,因此不能应用于类。因此,要么我们不能在自定义装饰器中包括 @HttpCode()
,并且在每个路由方法上手动使用它,允许我们在类级别使用我们的自定义装饰器。要么我们可以将其包含在我们的自定义装饰器中,但会失去在类级别使用装饰器的能力。
英文:
Turns out @HttpCode()
is a method decorator and therefore cannot be applied to class.
Therefore either we can not include @HttpCode()
in custom decorator, and use it manually on each route method, allowing us to use our custom decorator at class level.
Or we can include it in our custom decorator, and loose the ability of using the decorator at class level.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论