Nest.js is a powerful framework for building server-side applications using Node.js. It provides a modular structure and makes use of TypeScript to provide type safety and other benefits. One of the key components in a Nest.js application is the controller, which handles incoming requests and returns responses to the client.
In this tutorial, we'll walk through the process of creating controllers in Nest.js using TypeScript. We'll cover the basics of creating a controller, handling requests and responses, and creating endpoints for our application.
Prerequisites
Before we get started, make sure you have the following installed:
- Node.js (version 12 or higher)
- npm (version 6 or higher)
- A code editor (e.g. Visual Studio Code)
You should also have a basic understanding of TypeScript and Node.js.
Creating a Nest.js application
The first step is to create a new Nest.js application. Open up your terminal and run the following command:
$ npm i -g @nestjs/cli
$ nest new my-appThis will create a new Nest.js application in a folder called my-app.
Next, navigate to the my-app folder and install the necessary dependencies:
$ cd my-app
$ npm installNow we're ready to start building our controllers.
Creating a controller
A controller is a class that handles incoming requests and returns responses to the client. To create a new controller, we can use the @Controller() decorator provided by Nest.js.
Let's create a new controller called HelloController:
import { Controller, Get } from '@nestjs/common';
@Controller('hello')
export class HelloController {
@Get()
sayHello(): string {
return 'Hello, world!';
}
}Here, we've imported the Controller and Get decorators from the @nestjs/common package. We've also defined a new class called HelloController and used the @Controller() decorator to specify the endpoint for this controller (/hello).
Next, we've defined a new method called sayHello() and used the @Get() decorator to specify that this method should handle GET requests to the /hello endpoint. Inside the method, we're simply returning a string that says "Hello, world!".
Handling requests and responses
Now that we've created our HelloController, let's take a closer look at how it handles incoming requests and returns responses to the client.
Nest.js provides a number of decorators that we can use to handle different types of requests, including @Get(), @Post(), @Put(), @Delete(), and more. Each of these decorators can be used to specify the HTTP method that the controller should handle.
For example, to handle a GET request to the /hello endpoint, we use the @Get() decorator and define a method called sayHello() that returns a string:
@Get()
sayHello(): string {
return 'Hello, world!';
}Similarly, to handle a POST request to the /hello endpoint, we can use the @Post() decorator and define a method called createHello() that takes in a request body and returns a new resource:
@Post()
createHello(@Body() body: CreateHelloDto): Hello {
const hello = new Hello();
hello.message = body.message;
return hello.save();
}Here, we've used the @Post() decorator to specify that this method should handle POST requests to the /hello endpoint. We've also used the @Body() decorator to extract the request body and map it to a CreateHelloDto object.
Creating Endpoints
In addition to handling requests and responses, controllers can also define endpoints for our application. Endpoints are simply URLs that map to specific controller methods.
To define an endpoint, we can use the @Get(), @Post(), @Put(), or @Delete() decorators, depending on the HTTP method we want to handle. We can also specify a path for the endpoint using the @Controller() decorator.
For example, to define an endpoint for getting a list of hellos, we can use the @Get() decorator and specify a path of /hellos:
@Controller('hellos')
export class HelloController {
@Get()
getHellos(): Hello[] {
return Hello.findAll();
}
}Here, we've used the @Controller() decorator to specify a path of /hellos for this controller. We've also defined a new method called getHellos() that uses the Hello model to fetch a list of hellos from the database.
We can then make a GET request to the /hellos endpoint to retrieve the list of hellos.
Error handling
One important aspect of creating controllers is handling errors. When an error occurs in a controller method, we need to make sure that we return an appropriate error response to the client.
Nest.js provides several built-in exceptions that we can use to handle errors, including NotFoundException, BadRequestException, and InternalServerErrorException. We can also define our own custom exceptions by extending the HttpException class.
To throw an exception in a controller method, we can use the throw new syntax:
@Get(':id')
async getHelloById(@Param('id') id: string): Promise<Hello> {
const hello = await Hello.findOne(id);
if (!hello) {
throw new NotFoundException(`Hello with id ${id} not found`);
}
return hello;
}Here, we've defined a new method called getHelloById() that takes in a parameter called id. We've used the @Param() decorator to extract the id parameter from the URL.
We then use the Hello model to fetch the hello with the specified id. If no hello is found, we throw a NotFoundException with an appropriate error message.
Conclusion
In this tutorial, we've walked through the process of creating controllers in Nest.js using TypeScript. We've covered the basics of creating a controller, handling requests and responses, creating endpoints, and handling errors.
Controllers are a fundamental component of Nest.js applications, and mastering them is essential to building robust, scalable server-side applications. With the knowledge you've gained in this tutorial, you should now be well-equipped to start building your own controllers in Nest.js.