Validating numeric query parameters in NestJS

avantar

Krzysztof Szala

Posted on April 12, 2021

Validating numeric query parameters in NestJS

Another day, another short article. Today we will focus on validation of numeric query parameters.

Everyone values his/her time, so here is TL;DR:

Each query parameter comes as string, so it's not possible to validate numeric params correctly. Simple solution – use @Type() decorator from class-transformer library, and declare numeric field as Number. I.e. @Type(() => Number)

Let's take an example URL address with few query parameters:

https://awesomesite.com/users?country=6&name=joe
Enter fullscreen mode Exit fullscreen mode

Our controller would probably look like this:

@Controller('users')
class UsersController{
  @Get()
  getUsers(@Query() queryParams){}
}
Enter fullscreen mode Exit fullscreen mode

Ok, at the beginning we've extracted our query parameters with @Query() decorator. Time to impose some validation on them. Here is our validation class:

class GetUsersQuery{
  @IsInt()
  country: number;

  @IsString()
  name: string;
}
Enter fullscreen mode Exit fullscreen mode

We've defined very basic validation constraints for country and name fields. Then we need to do a little change in our controller method.

@Controller('users')
class UsersController{
  @Get()
  getUsers(@Query() queryParams: GetUsersQuery){
    console.log(queryParams)
  }
}
Enter fullscreen mode Exit fullscreen mode

Ok. Time to check if our validation works correctly. Let's try to send GET request for previously mentioned URL. Everything should be just fine, right? Well, not really, here is what we got:

{
    "statusCode": 400,
    "message": [
        "country must be a number conforming to the specified constraints"
    ],
    "error": "Bad Request"
}
Enter fullscreen mode Exit fullscreen mode

What? But country is anumeric field! It's even an integer! Unfortunately, not for our application. Let's try to make one step back, and remove validation, then check what kind of parameters will query object contain.

{ 
  country: '1',
  name: 'joe'
}
Enter fullscreen mode Exit fullscreen mode

Ok, now you can see, that each field is passed as a string value. Even an integer field. What can we do with it? After all, we need to validate whether the country field is an integer, or not, right?

Once again, class-transformer library has a simple solution for us. Use @Type decorator, and declare country field as Number:

class GetUsersQuery{
  @IsInt()
  @Type(() => Number)
  country: number;

  @IsString()
  name: string;
}
Enter fullscreen mode Exit fullscreen mode

Now our request will pass validation, and the response object will look like this:

{ 
  country: 1,
  name: 'joe'
}
Enter fullscreen mode Exit fullscreen mode

Country field has numeric type now. When we send an invalid value, for example, a string, we'll get:

{
    "statusCode": 400,
    "message": [
        "country must be an integer number"
    ],
    "error": "Bad Request"
}
Enter fullscreen mode Exit fullscreen mode

But for integer type parameter it will pass. Finally, our integer validation works now correctly. Hope this short article will help you to validate numeric values passed through URL parameters. Cheers!

💖 💪 🙅 🚩
avantar
Krzysztof Szala

Posted on April 12, 2021

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related

Getting started with NestJs
javascript Getting started with NestJs

February 18, 2023

Getting Started With NestJS
javascript Getting Started With NestJS

January 2, 2020