Nest.js controllers

Nest.js controllers

What are controllers?

Controllers in Nest.js are classic TypeScript classes that are decorated with the @Controller() decorator. In such classes, methods corresponding to HTTP operations such as GET, POST, PUT, DELETE are defined, where each method within the controller is decorated with a corresponding HTTP decorator.

Example of a simple controller:

In this example, the @Controller('users') decorator defines the base route (“/users“) for all methods inside the controller. This example controller has three methods for three request types, and all three methods are marked with appropriate decorators depending on the type of HTTP request they handle:

  • findAll(): Processes a GET request on route /users and returns a list of all users.
  • findOne(): Processes a GET request on route /users/:id and returns the user with the given ID.
  • create(): Processes a POST request on route /users and creates a new user.

nest.js

Creating a controller

To add a controller to a module, the easiest way is to use the following commands in the terminal:

This command will generate a users.controller.ts file within the new folder “users” and will place it in the root of the project, i.e. src/users:

NOTE:
If a directory named “users” does not exist, this command will create it. If we do not want to create a folder with the name of the controller, but only the controller file, then we use the flag --flat.

The previous command will create in the root directory (“src”) only a file related to the controller nekiKontroler.controller.ts, there is also a way to create a new controller file in an already existing folder, and for that we use the following syntax:

With this command, the file “noviKontroler.controller.ts” will be created in the folder named “nekiFolder”.

The command will also simultaneously add that controller to the module within the list of all controllers:

Decorators for accessing request data

In addition to decorators for marking the type of request (@Get(), @Post()…), there are also decorators for easier access to request data. These decorators make it easier to work with different parts of an HTTP request and allow simple and readable handling of requests inside the controller:

  • @Param('id'): Allows access to parameter id from URL
  • @Body(): Allows access to the POST request body.
  • @Headers() provides access to HTTP headers.
  • @Ip() provides access to the client’s IP address.
  • @Body() provides access to the POST request body.
  • @Session() provides access to session data.
  • @Cookies() enables access to cookies.
  • @HostParam('host') provides access to host parameters.
Example

Here’s how you can use some of these decorators in a controller:

In the previous example, the @Get decorator indicates that the findOne() method will respond to the request. The @Param(‘id’) decorator extracts a parameter named “id” from the request URL, while the @Query() decorator extracts all query parameters from the request URL and stores them in the “query” object (eg for the URL /users/123?search=test, the query will be { search: ‘test’ }). The @Ip() decorator provides the IP address of the client that sent the request.

Availability of services in controllers

Services are used to encapsulate business logic and enable code reuse. Services can be easily introduced into controllers using the dependency injection mechanism whichprovided by Nest.js. In Nest.js, there are several ways to inject services into a controller.

Injecting services through the constructor

The most common way is through constructors, as shown in the following example:

In this example, UsersController uses UsersService to process the request. The service is inserted into the controller through the constructor.

Injecting services through a property

Although not so often used, service injection via properties is also possible using the @Inject decorator.

NOTE:
There is also “Manual injection” of services but it is quite complicated and is only used in specific cases when you cannot use constructor or property-based injection. This approach uses ModuleRef, which provides access to the Nest.js Dependency Injection (DI) container to manually obtain service instances.