Nandhakumar's Display Picture

Nandhakumar

Dec 15, 2022

6 min read

Nest JS Tutorial #3 : Query & Route Params

#nestjs

#javascript

#typescript

#backend

#api

Nest JS Tutorial #3 : Query & Route Params

Hi There! 👋

In this post, you will learn what is route & query param, when to use it and how to use it in Nest.JS

This post is a part Nest JS tutorial series, Do check out my other post on nest js to know more about it.

Let's Get Started Now! 🚀

Prerequisite

Understanding Route and Query param

Route Param

Route Params are used to get specific data.

Example Scenario, Let's say you want to get a user detail by ID, so ID can be will be passed as a route param like this 👇

http://api.com/5689

Here, 5689 is the ID of the user

Query Param

Query params are used when you want to filter, sort and paginate the data.

Example Scenario, Let's say you want to get a list of users that matches a name. so, here name can be passed as a query param like this 👇

"http://api.com?name=tamilan"

Here, the name tamilan is passed as a query param. To get results matching the name.

You can also pass multiple query param.

In addition to filter by name, we can also add a sort query with the existing name query like this 👇

"http://api.com?name=tamilan&sort=name"

That's a short brief on route and query param!

Now let's see how to capture these query and route param in nest js.

Using Route and Query Param in Nest JS

To get started, Create a new nest project using nest cli. If you are not sure how to create a new project, check out this post

I have created a new nest project, with its starter code.

Here's the project structure I have now,

Nest JS Starter Project Structure

Requirements

We need two routes,

  • /user
    • It should be a GET request
    • It should return all the users when there is no query param
    • It should return all the users that match the name when the name query param is passed
  • /user/:id
    • It should be a GET request
    • It should return the user that matches the id passed as a route param

Implementation

Step 1:

Add some mock user data to the service file.

As we are using typescript it would be nice to add an interface for the user.

// app.service.ts

import { Injectable } from '@nestjs/common';

// user interface
export interface IUser {
  id: number;
  name: string;
  age: number;
}

@Injectable()
export class AppService {
  // list of users
  private users: IUser[] = [
    {
      id: 1,
      name: 'Tamilan',
      age: 23,
    },
    {
      id: 1,
      name: 'Nandha',
      age: 24,
    },
    {
      id: 1,
      name: 'Nandha Kumar',
      age: 24,
    },
  ];
}

Step 2:

Create a method findUsersByName that returns users matching the 'name' query or all the users when there is no name query.

Add this method to the same service file

findUsersByName(nameToBeMatched: string): IUser[] {
    return nameToBeMatched
      ? this.users.filter((user) =>
          // return users with name matching
          // 'name' query param
          user.name.toLowerCase().includes(nameToBeMatched),
        )
      : // returns all the users if the
        // 'name' query param is 'null' or ''
        this.users;
  }

Step 3:

Create another method findUserById that returns a user matching the id route param.

Add this method to the same service file.

findUserById(id: string): IUser {
    // return user with id matching 'id' route param

    // By Default when you get value from query or route
    // param it will be string, But in our case user id is of
    // type number. So we are making a type conversion for id
    return this.users.find((user) => user.id === Number(id));
}

Step 4:

Update the base route of the controller to /user

 // app.controller.ts
import { Controller, Get} from '@nestjs/common';
import { AppService, IUser } from './app.service';

@Controller('/user') // update the base route to '/user'
export class AppController {
  constructor(private readonly appService: AppService) {}

}

Step 5:

Implementing the first part of the requirement.

Create a method getUsers with @Get() decorator.

And it should take @Query() decorator as its argument. So that whenever we add the query to the URL, those params will be captured by this argument.

In the implementation pass the query params to the service method(findUsersByName) that we have already implemented in the service

Finally, return the data

 // app.controller.ts
import { Controller, Get} from '@nestjs/common';
import { AppService, IUser } from './app.service';

@Controller('/user')
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getUsers(@Query() params: any): IUser[] {
    return this.appService.findUsersByName(params.name);
  }
}

Pro Tip

If you want a specific property from the query, you can specify the property name in the @Query() decorator like this 👇


@Get()
  getUsers(@Query('name') name: string): IUser[] {
    return this.appService.findUsersByName(name);
  }

Step 6:

Implementing the second part of the requirement.

Create a method getUserById with @Get(':id') decorator.

Note :
Here we have defined :id route param in the @Get() decorator.

And it should take @Param() decorator as its argument. So that the route param will be captured by this argument.

In the implementation pass the query params to the service method(findUserById) that we have already implemented in the service.

Finally, return the data.

// app.controller.ts
import { Controller, Get, Param, Query } from '@nestjs/common';
import { AppService, IUser } from './app.service';

@Controller('/user')
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getUsers(@Query() params: any): IUser[] {
    return this.appService.findUsersByName(params.name);
  }

  @Get(':id')
  getUserById(@Param() params: any): IUser {
    return this.appService.findUserById(params.id);
  }
}

Pro Tip

Similar to the @Query() decorator you can specify the property id in the @Param() decorator like this 👇


@Get()
  getUsers(@Param('id') id: string): IUser {
    return this.appService.findUsersByName(id);
  }

That's it!

As per the requirement, you have implemented the API.


Testing

Let's test the implementation now!

Start the server by executing,

npm run start:dev

Open the server URL http://localhost:3000 in Postman or any API Testing Tool.

Test Case 1:

Getting all Users, without query params.

Nest JS Query and Route Param, Test Case - 1

And we got all the users.

✅ Test Case Passed!

Test Case 2:

Getting all Users, with name query param

Nest JS Query and Route Param, Test Case - 2

And we got all the users matching the name passed in the query param.

✅ Test Case Passed!

Test Case 3:

Getting User by id, with id route param.

Nest JS Query and Route Param, Test Case - 3

And we got the user with the id we passed in the route.

✅ Test Case Passed!

Try implementing different scenarios with multiple Query and Route params.

Congratulation! 👏

You have successfully implemented APIs with Query and Route param in Nest.JS.

Get the completed source code from here.


Thanks For Reading!

Hope you have learned something new today 😊.

I welcome your questions, feedback, and discussions on this topic. Don't hesitate to reach out if there's something you'd like to talk about.

If you find this post helpful Tweet this Post

Follow and connect with me on Twitter, Instagram, Email and LinkedIn for more interesting stuff like this.

Cheers ✌️