• Labs icon Lab
  • Core Tech
Labs

Guided: Controllers and Routing in NestJS

In this hands-on lab, you'll build a fully functional controller with routes for a NestJS application. Throughout the lab, you will implement essential CRUD operations for this application using the unique suite of decorators and design patterns provided by NestJS.

Labs

Path Info

Level
Clock icon Beginner
Duration
Clock icon 40m
Published
Clock icon Feb 27, 2025

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Table of Contents

  1. Challenge

    Introduction

    Controllers and Routing

    Controllers and routing are fundamental concepts in web development that define how an application handles incoming requests and directs them to the appropriate logic.

    Controllers act as intermediaries between client requests and the application's business logic, processing input and returning responses. Routing determines how different URLs map to specific controller actions, enabling applications to handle various endpoints, HTTP methods, and parameters.


    NestJS Controllers and Routing

    In NestJS, controllers are responsible for handling incoming requests and returning responses, acting as the entry point for the application’s routing system. They use decorators to define routes and map them to specific handler methods. Routing in NestJS is built-in and allows for dynamic parameters, nested routes, wildcards, and request handling using a declarative approach, making it easy to organize API endpoints efficiently.


    Working with the Application

    You will be responsible for setting up the controller and routing for the provided Nestjs in this lab. As you progress through the lab, you can interact with it when running the application through the Swagger interface, which can be found in the Simple Web Browser tab after you have run the application.

    You can run the application in the Run Server terminal with either npm run start or npm run start:dev. The start:dev version will set it in watch mode, which will dynamically refresh whenever you make any changes to files.

    There is also a solution directory for you to check your implementations at any time.

    Lastly, if you wish to format your code after making edits, you can use prettier to do so. First, head to .prettierignore and remove the two ** and save the file. Then run npm run format to clean up your code. If you wish to turn prettier off, add the ** back to prettierignore and save it.

  2. Challenge

    Setting up the Controller

    In this step, you will setup the controller and GET requests for the NestJS application.


    Review the item.controller.ts

    Open the src/item/item.controller.ts file. Inside this file, you will find a partially generated file for your controller which you will need to finish for this lab.

    If you take a look at src/item/item.module.ts, you will see that the ItemModule has registered this ItemController along with an ItemService. You won't have to worry about the ItemService as it has already been implemented for you.

    The main applications app.module.ts registers this ItemModule, which by proxy also registers the ItemController for use by the application. With this, your default response when accessing the ItemController at /item/ will be to display all items. Keep in mind that the ItemService initializes an empty array of items, so don't be surprised if your response returns an empty body at first. Establishing this route will allow you to search for any items whose name includes the provided term. For instance, accessing the endpoint with /item/byname/search?term=gamma would retrieve all items whose name contains the term gamma.


    Another behavior that occurs in these applications is redirection. NestJS allows you to redirect to a new URL with its @Redirect() decorator. Enabling this behavior is no different from how you attached other decorators to the previous route handlers.

    There are route handlers you will need to work with for this. There is redirectRoute(), which returns nothing. Then there is targetRoute(), which returns an object with a message. You will need to apply redirection from redirectRoute() so that it points to targetRoute(). A recurring theme here is that the NestJS framework provides decorators to cover most of the functionality you will need for everyday use in your applications. However, there may be times where you would need to utilize the full response object for various reasons. This typically enables greater flexibility, but has the side effect of making your implementations less design-agnostic due to differing behaviors between library APIs. Wildcard routes are designed to be a "catch-all" for requests that don't match any pre-established endpoints. Since endpoints are defined on a first come basis, you need to define wildcard routes last or they will catch incoming requests that may be aimed towards legitimate endpoints. ## Conclusion

    You have successfully setup your controller and some key routes for your NestJS application. Next, you will look into implementing the rest of the routes needed for your application to support all the CRUD operations.

  3. Challenge

    Finishing up the CRUD Routes

    In this step, you will implement the rest of the route handlers to support CRUD operations for your NestJS application.


    First, you need to setup a POST route to create items through the controller. Scroll down to the section labelled by the comment OTHER REQUESTS. You will need to add a route for the create() method. Now you can add items through your controller and you can use the default GET route to display your items after adding them through the POST route.


    Next, you need to setup a PUT route to replace items through the controller. Look in the same OTHER REQUESTS section. You will need to add a route for the replaceItem() method. Next, you need to setup a PATCH route to update items through the controller. Look in the same OTHER REQUESTS section. You will need to add a route for the update() method. Next, you need to setup a DELETE route to remove items through the controller. Look in the same OTHER REQUESTS section. You will need to add a route for the remove() method. For this particular route, you will also be using the HttpCode decorator which will override the default status code that is returned from an http request. ## Conclusion

    You have successfully setup all the routes and CRUD operations for your controller. The last thing you will need to look into next will be to ensure that incoming data is valid for processing.

  4. Challenge

    DTOs

    In NestJS, DTOs (Data Transfer Objects) define the shape of data exchanged between the client and the server. They are implemented as TypeScript classes and often use validation decorators from libraries like class-validator to ensure data integrity. By integrating with NestJS's piping system, DTOs enable automatic transformation and validation of incoming requests before they reach the application logic.


    DTO Folder

    NestJS has a built-in CLI command for generating controllers or even entire resources(amalgamation of controllers/providers/etc. bundled in one module). When using this command, one directory it will also bootstrap is the dto directory which contains a create-resource.dto.ts and an update-resource.dto.ts file. These files ostensibly contain classes for their respective DTO's, which you may have noticed were used as parameters for some of the route handlers you implemented in the previous steps.

    These DTO's are necessary to ensure that the data these route handlers receive is in the expected format. For this lab, you will only need to modify create-item.dto.ts. The update-item.dto.ts utilizes PartialType, a NestJS feature that lets it inherit from create-item but marks all fields as optional. While there are ways to modify it, the default behavior from inheriting properties from create-item will suffice for this lab.


    The CreateItem class in create-item.dto.ts currently contains a name property and an optional description property. You will need to add validation decorators to ensure that these properties are of the correct type. Now that you've setup validation for your DTO, you will need to bind a ValidationPipe to the application to ensure that any data being sent to endpoints expecting a DTO contains proper data. ## Conclusion

    If you've made it here then you have successfully setup all the CRUD operations along with some other useful routes for your NestJS application. Furthermore, you've also incorporated the NestJS DTO pattern to ensure the validity and integrity of incoming data for your controller routes.

    Great job on completing this lab!

George is a Pluralsight Author working on content for Hands-On Experiences. He is experienced in the Python, JavaScript, Java, and most recently Rust domains.

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.