NestJS — Creating custom parameter decorators for your APIs with createParamDecorator()

If you have played with NestJS for a while, you should have been familiar with decorators. It is because NestJS utilized decorators to do the declaration, configuration and assignment of your objects. You should have seen them everywhere.

Here are five decorators that you may already have been frequently using for creating APIs: @Session, @Param, @Body , @Query and @Headers , which access req.session , req.params , req.body , req.query and req.headers correspondingly.

However, what if you want to access your custom request attributes, such as req.jwt ?

Custom parameter decorators with a key

Actually, NestJS already has a built-in function for you to create such custom decorators — createParamDecorator()

Very simple, isn’t?

In default, the decorator created will accept 1 optional parameter, which is data . One common way to utilize it is to put the attribute key there.

As a result, if you put @Jwt() , it will assign the whole req.jwt object to your variable. If there is a key provided, such as @Jwt('memberId') , it will assign req.jwt.memberId instead.

In fact, you can find a similar section at the official document. Hence, I am going to add something that you cannot find from that document in the next section.

Custom parameter decorators with multiple options

The problem here is, having a key can solve most use cases, but what if only a key is not enough? Suppose you want to add validation in your custom parameter decorator — if req.jwt is null, it will throw an exception. However, you want some of the APIs to be able to bypass the validation.

The simplest way is to create two different decorators — @Jwt and @JwtNullable, one with validation, one without. It will work perfectly fine, except it is a bit ugly. Also, it will be problematic when you have multiple options.

Another simple way is to wrap the key and all your options into a single object. It is slightly better than the previous one, but still not ideal as you need to wrap the key into an object even if there isn’t any options.

My solution is actually simpler than you may think. The key point here is that, decorators are in fact, just functions. What you need to do is to create a wrapper function in between.

You are creating a function which accepts two parameters — key and options. Instead of directly using the decorator created with createParamDecorator() in your controller, you are now using your custom function as decorator, which helps you to transform your parameters into a single object. As a result, you can encapsulate the ugly part and keep the decorator clean.

When to use createParamDecorator()?

I have written another article about creating decorators from scratch for API validation previously and I didn’t use createParamDecorator() there. Simply speaking, you should use createParamDecorator() only if you are creating parameter decorators, and your decorator is interacting with the req object. If your decorator has nothing to do with the API request, createParamDecorator() will not help.

Web developer from Hong Kong. Most interested in Angular and Vue. Currently working on a Nuxt.js + NestJS project.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store