NestJS Overview === ![](https://i.imgur.com/UhikMug.png) ## I. What is it It's a progressive Node.js framework for building efficient, reliable and scalable server-side applications. So where the hype comes from? Why can i just use ExpressJS? Here's why: - Inherits all the pros of ExpressJS because it was built up on Express.js - Enforce a clear project structure - Embraces Typescript, Dependency Injection, and Modularity If you've ever used Angular or Springboots, you might see some similarities. ## II. Overview ### 1. Installation ``` $ npm i -g @nestjs/cli $ nest new project-name ``` Use these command lines to install a Nest project. After installed, you can see that project has a default structure and pre-installed library like jest (for testing) or typescript (for type checking). ![project structure](https://i.imgur.com/xkFzr6V.png) Although there're options for accepting non-typescript files in `nest-cli.json`, I personally think that there is no point of using NestJS if you do that. - `main.ts` : this is where Nest bootstrap your app. - `app.module.ts` : as mentioned earlier, NestJS imbraces modularity, which means that our application is a combination of separate modules. All module should be added in this app module for the app to know what modules included in the application. - `controller.ts` : is where you handle your http requests, where you return response to those request - `service.ts` : is a kind of providers. > Providers are a fundamental concept in Nest. Many of the basic Nest classes may be treated as a provider – services, repositories, factories, helpers, and so on. The main idea of a provider is that it can be injected as dependency; this means objects can create various relationships with each other, and the function of "wiring up" instances of objects can largely be delegated to the Nest runtime system. --- **CRUD generator** : is a simple way to create new resources ``` nest g resource ``` This command not only generates all the NestJS building blocks (module, service, controller classes) but also an entity class (this represent a data table, <u>Ex:</u> entity class User represent User table, class properties would be firstName, lastName, age, ...), DTO classes (where you define types and condition, if any, for request and response object) as well as the testing (.spec) files. <u>Ex:</u> I would like to create enpoint for Product entity, type `nest g resource products` to create a folder dedicate to `/products` endpoint. ![](https://i.imgur.com/ffAkYM9.png) --- **Decorator** and **Pipe** : you will see that decorator and pipe are used throughout the app and they play an important role in making it easy to use Nestjs. There're not only built-in decorators and pipes but you can also create customs decorators and pipes that suit you. If you're not familiar with decorator and pipe concept, i suggest to take a look at below to get a general idea. <u>pipe</u> : https://morioh.com/p/3cdedeb17367 <u>decorator</u> : https://saul-mirone.github.io/a-complete-guide-to-typescript-decorator/ ### 2.Create an API When you create an API with Nestjs, here's what you should look into: - **Database** Nest allows you to easily intergrate with SQL or noSQL database. Beside the traditional way of connecting and handling database, Nest has tight intergration with TypeORM, Sequelize, Mongoose for additional features such as model/repository injection, testability, and asynchronous configuration to make accessing your chosen database even easier. Choose the ORM of your favorite and install it. Then import and configurate it in `app.module.ts`. Below is an example of using TypeORM and mySQL: ``` import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; @Module({ imports: [ TypeOrmModule.forRoot({ type: 'mysql', host: 'localhost', port: 3306, username: 'root', password: 'root', database: 'test', entities: [], synchronize: true, }), ], }) export class AppModule {} ``` or, you can create an `ormconfig.json` file and leave the `forRoot()` empty ``` { "type": "mysql", "host": "localhost", "port": 3306, "username": "root", "password": "root", "database": "test", "entities": ["dist/**/*.entity{.ts,.js}"], "synchronize": true } ``` Once this is done, the TypeORM Connection and EntityManager objects will be available to inject across the entire project (without needing to import any modules) and you can start using ORM syntax to query data. One thing to keep in mind is that to be able to use ORM, you need to have entity/model/both (depends on ORM you choose), each represents a data table in your database. Details integration can be found here: https://docs.nestjs.com/techniques/database - **Controller** > Controllers are responsible for handling incoming requests and returning responses to the client. ![](https://i.imgur.com/HzO9Pzp.png) To create a controller, simply add `@Controller()` above the controller class you're about to create. ``` @Controller() export class AppController { constructor(private readonly appService: AppService) {} @Header('Content-Type', 'text/html') @HttpCode(204) @Get(':id') findOne(@Param() params) { console.log(params.id); return `This action returns a #${params.id} cat`; } } ``` Inside the bracket of controller decorator is the API route that the controller is dedicated to. <u>Ex:</u> `@Controller()` handle all requests for `your-domain/`, `@Controller(products)` handle all requests for `your-domain/products` There're decorators represent the CRUD acions (`@Get()`, `@Post()`, `@Patch()`, `@Delete()`) to define what function handle what kind of http request and other decorator to handle other thing like: header, respond code, etc... And, inside the parameters of function that return response, there're decorators to access params, queries or request body. ![](https://i.imgur.com/25sdTxc.png) Below is the controller that is created for you, if you use **CRUD generator** ![](https://i.imgur.com/qTF92jJ.png) - **Providers** are injectable class that allow to share logic throughout entire app. Any class that has decorator `@Injectable` can be injected in the constructor of other class. <u>Service</u> is a provider. You're not obliged to use, you can just handle and return the response right at controller. However, the idea is to keep all the thing that you want to do with the response, either light or heavy logic, in the `service` and `controller` only has to return response. Below is the service that is created for you, if you use **CRUD generator** ![](https://i.imgur.com/eFEaPSf.png) <u>Guard</u> is another provider that can be use to handle authentication. https://docs.nestjs.com/security/authentication#jwt-functionality <u>Pipe</u> is a provider that can be injected to controller to validate and transform a value in controller. Beside built-in pipes, you can create your own pipe to transform data as you wish. > Pipes have two typical use cases: >- transformation: transform input data to the desired form (e.g., from string to integer) >- validation: evaluate input data and if valid, simply pass it through unchanged; otherwise, throw an exception when the data is incorrect https://docs.nestjs.com/pipes - **Module** > A module is a class annotated with a @Module() decorator. The @Module() decorator provides metadata that Nest makes use of to organize the application structure. ![](https://i.imgur.com/7LlAlEj.png) So, remember to import individual modules in your root module so that the app knows what to run. Every module is automatically a shared module. Once created it can be reused by any module, as long as you import it in the other module that you wan to use. Each module will have an object of properties to describe it: <u>providers</u> : are any injectable classes that will be used in this module <u>controllers</u> : the set of controllers defined in this module which have to be instantiated <u>imports</u> : if you want to use any injectable classes of another modules, list those module in `imports` array, and you can use the logics without having to write them again. <u>exports</u> : in other for provider of a module to be imported in other modules, you need to export it. ![](https://i.imgur.com/pHYKhqM.png) ## III.Conclusion Reading the doc might be a bit overwhelming at first. Although it seems complicated, nestjs is actually easy to start with, if you want to create a small app, just install it, connect database, add controller to return response, add service to handle respose before return (if you want to), then if you need authorization, add a guard, which is actually well written in the doc, just modify it as you need and you're good to go. And you don't have to worry about scaling the app later, if you don't need to scale it, leave it as is, but if you want to scale it, everything is in structure, ready for you. <small> Published date: 2022-03-04 <br/> Also published <a href="https://medium.com/goalist-blog/nestjs-overview-b1cdf323767a">here</a>. </small>