NestJS: Controllers
Tags: javascript, webdev, nestjs, node
Published: 2022-05-31 07:58:47

Controllers have become widely used in MVC. Controllers serve as an entry point. They receive a client request from the route and pass it on. After processing the request, the controller generates a response from the received data. The controller sends this response back to the client.

NestJS also has controllers. It's actually an ES6 class wrapped in the `@Controller` decorator, which is imported from '@nestjs/common'. 

Controllers can be created by special command in command line. We can use nest CLI for that.

```
nest g controller products
```

Here: 
- 'g' means generate
- 'controller' - what we want generate 
- 'products' - is a controller name.

But also, you can create controller by yourself without CLI.

All controllers in NestJS are regitstrated in Module.
Let take a look on code:

```
import { Controller, Get } from '@nestjs/common';

@Controller('products')
export class ProductController {
  @Get()
  getAllProducts(): Product[] {
    // Code...
    return products;
  }
}
```

This decorator has an optional string type argument - this is the part of path or its prefix. This URL receives a request from the client. Within the controller class, methods are defined - handlers which will work with request from client. Methods are also wrapped in decorators by the name of HTTP methods - `@Get, @Post, @Put, @Delete, @Patch, @Options, @Head`. Each of these decorators also takes an optional string type parameter, the final path. Thus, the prefix set in the controller argument and the path specified in the method decorator define the endpoint.

```
import { Controller, Get, Post } from '@nestjs/common';

@Controller('products')
export class ProductController {
  @Get()
  getAllProduct(): Product[]{
    // Code...
    return products;
  }

  @Post()
  create(): string {
    // Code...
    return 'Product has been added';
  }
}
```

All of these method names match the HTTP methods that the handler will expect. Those, if there is set a `@Post()` decorator on a certain endpoint, then when forming a request for this endpoint from the client side, it is necessary to indicate that the HTTP POST method will be used. Otherwise, you will receive a response that this method is not available.

By default, if the processing was successful, the controller returns a status of 200 with the response. This behavior can be changed using the @HttpCode decorator at the request handler level. If your response status inside a controller method will depend on various factors, then you can use a specific response object. To do this, you need to inject an argument with the `@Res()` decorator into the method.

```
import { Controller, Get, Post, Res, HttpStatus } from '@nestjs/common';
import { Response } from 'express';

@Controller('products')
export class ProductController {
  @Get()
  getAllProduct(@Res() res: Response) {
     // Code...
     res.status(HttpStatus.OK).json(products);
  }
}
```

Controllers in NestJS allow us to easily create APIs - if an object or array is returned from the controller, that object or array is automatically serialized to JSON. Primitive types (string, number, boolean, etc.) are returned without serialization.

The `@Req()` decorator is used to receive and process a request from the client. Just like with the response, you need to inject the argument with the given decorator into the method. And after that we can work with the request object.

```
import { Controller, Get, Req } from '@nestjs/common';
import { Request } from 'express';

@Controller('products')
export class ProductsController {
  @Get()
  getAllProducts(@Req() request: Request): Product[]{
    // Code...
    return products;
  }
}
```

If you need to set specific response headers in a separate method, then this can be done using the `@Header()` decorator.

I also want tell how to work with GET request parameters. It happens that certain GET parameters are passed from the client in the path string. In order to process them, you need to pass a certain argument to the method decorator.

```
import { Controller, Get, Param } from '@nestjs/common';

// Code...
@Get(':id')
findOneProduct(@Param() params): Product {
  console.log(params.id);
  // Code...
  return product;
}
```

In general, this is all the basic knowledge about controllers in NestJS that you need to start writing your application. NestJS provides great opportunities for working with controllers - you can see about them in the documentation on the framework website.

Thanks for your attention!