In this post, we will look at how to create a NestJS Custom Decorator. As you must have seen, NestJS is built around the concept of decorators that makes it easy to construct programs with declarative syntax.

Knowing how to create our own decorator can be handy to increase reusability.

So let’s start.

1 – What is a Decorator?

Decorators are quite common in many programming languages. However, they are relatively new in the world of Javascript.

A decorator is an expression that returns a function. It can take a target, name and property descriptor as arguments. We apply a decorator with an @ character and place it at the top of what we are trying to decorate.

We can define decorators for class, method or a property.

NestJS provides a set of param decorators. We can use them with HTTP route handlers. Some of the common decorators are @Request() or @Req(), @Response() or @Res(), @Body(), @Query() and so on.

However, we can also create custom decorators to suit our specific needs.

2 – Creating a NestJS Custom Decorator

Let us consider a use case where we want a custom decorator that we can place on a method-level. Basically, we expect this decorator to take in an object and extract a particular property from that object.

Below is an example of a custom decorator.

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

export const User = createParamDecorator(
    (data: string, ctx: ExecutionContext) => {
        const request = ctx.switchToHttp().getRequest();
        const user = request.body.user;
        return data ? user?.[data] : user;
    }
);

As you can see, we use the createParamDecorator() function. This function receives the incoming data as well as the ExecutionContext. We use the ExecutionContext to extract the request object. Then, we extract the user object from the request object. Finally, we return the input key from the user object.

This is a very simple decorator. But using the same concept, we can also write complex logic to carry out some operations.

3 – Using the Custom Decorator

We can simply use the custom NestJS Decorator by annotating any method.

Below is an example of using our decorator in a controller. If you wish to know more about controllers, refer to this detailed post on NestJS Controllers.

@Post('/employees')
createEmployee(@User('firstName') firstName: string) {
    console.log(firstName);
}

Basically, we use the @User() decorator and pass a string firstName to the decorator. This is the key we wish to extract from the incoming user object. NestJS will automatically extract the value of firstName and assign it to the firstName variable as input.

Below is a sample input.

{"user":{"firstName":"Adam"}}

Basically, when our decorator receives the above input in the request body, it will extract the value of firstName i.e. Adam. In other words, developers do not have to write the repetitive logic to extract this property in case the same thing is required in other handlers as well.

As you can guess, decorators increase code reusability.

4 – Conclusion

With this, we have understood how to create a custom NestJS Decorator. We also looked at how to use it in our application. Basically, we created a reusable decorator that can be used across multiple request handlers.

If you have any comments or queries, please feel free to write in the comments section below.


Saurabh Dashora

Saurabh is a Software Architect with over 12 years of experience. He has worked on large-scale distributed systems across various domains and organizations. He is also a passionate Technical Writer and loves sharing knowledge in the community.

2 Comments

Steve · May 22, 2022 at 9:30 pm

Hi, very much enjoying your NestJS series, lots of valuable insights.

I have a comment about your decorator example. In the code there is the line that returns user?.[data] if data exists and user if not. But, the decorator is being applied to firstName, which is a string type. Would this lead to an error in the case of data not being defined, and then the decorator returning the user object instead of a string?

Best, Steve

    Saurabh Dashora · May 23, 2022 at 1:53 am

    Hi Steve…Thanks for the nice feedback!

    Regards to your question, I believe it won’t be an error. You’ll get undefined as the output in case data is not defined.

Leave a Reply

Your email address will not be published. Required fields are marked *