Exploring the Power of TypeScript Custom Decorators to extract user from request Tokens in Nest JS

Introduction

Kasun Abaywardana
2 min readJun 27, 2023

Decorators are a powerful language feature that enriches the functionality of classes, methods, properties, or parameters in programming languages. They provide a way to modify or enhance the behavior of these elements without directly modifying their original code. Decorators act as metadata attached to declarations and are executed during runtime, allowing for dynamic and flexible programming.

When do we need decorators?

Decorators are useful in various scenarios where you need to modify or extend the behavior of classes, methods, properties, or parameters without directly modifying their original code. Here are some situations where decorators can be particularly beneficial:

  1. Extending Functionality.
  2. Dependency Injection.
  3. Metadata and Reflection.
  4. Aspect-Oriented Programming (AOP).
  5. Customizing Framework Behavior.

Let's jump to an example

    @HttpCode(HttpStatus.OK)
@Post('create')
@UseGuards(JWTGuard)
createBookmark(
@GetUser('id') userId: number,
@Body() dto: CreateBookMark
) {
return this.bookmarkService.createBookmark(userId, dto);
}

This is the function that creates a POST request. In this function, we have 2 decorators: @GetUser and @Body(). The @GetUser decorator is custom-made and defined at the developer level, while the @Body() decorator is defined by Nest JS itself. Both decorators serve a similar primary purpose, but the key difference lies in the fact that the custom decorator functionality can be customized by the developer. Now, let’s delve into the declaration of the custom decorator.

import {
createParamDecorator,
ExecutionContext,
} from '@nestjs/common';

export const GetUser = createParamDecorator(
(
data: string | undefined,
ctx: ExecutionContext,
) => {
const request: Express.Request = ctx
.switchToHttp()
.getRequest();
if (data) {
return request.user[data];
}
return request.user;
},
);

Actually, this decorated process processes the token and extracts the user by using the token. This reduces the number of lines we need to repeat in each and every request and makes the code cleaner. While handling requests inside the function, we can easily refer to the user data without any hassle.

In conclusion, the example demonstrated the usage of both custom and built-in decorators within NestJS. By leveraging decorators, developers can enhance the functionality of their applications, reduce repetitive code, and maintain cleaner and more organized codebases. Decorators serve as a powerful tool in the NestJS framework for building scalable and efficient applications.

Happy coding!

--

--

Kasun Abaywardana

Kasun Abaywardana: 7+ yrs software dev exp. JS specialist in React, Node, Angular, MongoDB. Passionate about creating innovative solutions.