Nest.js is a node JS back-end development framework, which implements MVC mode and supports IOC (automatic dependency injection), which is one level higher than the request response library such as Express. It is also easy to integrate GraphQL, WebSocket and other functions, and is suitable for large-scale enterprise development.
Nest.js is widely used at home and abroad. Let's get started today: make a note management function, add, delete, modify and query mysql single tables, and provide a Restful interface.
There are many contents to be introduced later. Let's take a look at the final effect first:
The complete code is uploaded to GitHub: https://github.com/QuarkGluonPlasma/nestjs-exercize
Nest.js + Typeorm Foundation
mysql database and Typeorm
Start with the database far from the front end.
Download mysql on the mysql official website, install and start the service.
At this time, you can use the command line to write sql and operate the database.

But the command line operation is not convenient enough, so we have to download a mysql client with interface. I use navicat here.

It can visually create databases, tables, etc. it can write sql in the editor and then execute it. For example, in the figure, I created a hello database and a pile of tables.
Node.js code can also connect to the database service, and then remotely execute sql to add, delete, modify and query the database tables.
But directly executing sql is cumbersome. Can I only operate on objects and automatically execute sql to synchronize the database when the object properties change? It's like vue's data has changed to the auto synchronization view.
The mapping between database and object relationship is called ORM (Object Relational Mapping), that is, mapping tables into objects, and mapping the association between tables into the relationship between objects. Then, the operations on objects will be synchronized to the database through sql.
Typeorm is a framework for implementing orm. You can describe the mapping relationship through decorators, such as @ Entity, @ Column and @ primarygenerated Column
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"; @Entity() export class Note{ @PrimaryGeneratedColumn() id: number; @Column() title: string; @Column() content: string; }
If the relationship is declared through the decorator, after the database connection is established, we only need to operate on the object, and Typeorm will automatically execute sql to synchronize the changes to the database.
In this way, the operation, addition, deletion, modification and query of the database table are realized.
After the database part is done, let's move on to the part dealing with requests.
http request and nest js
The back-end framework for processing requests, we use nest JS, which provides the division of Controller and Service, which is the implementation of MVC mode.
The Controller is responsible for processing requests and passing the processed parameters to the service.
Service is responsible for the implementation of business logic. It implements various upper level business logic based on the addition, deletion, modification and query function of Typeorm.
In addition, nest JS also divides the Module. This Module is a logical Module, which is different from the Module corresponding to the file we often say. It includes Controller, Service, etc. it is a logical division of these resources.

There can also be dependencies between modules, that is, imports and exports.
Therefore, the module declaration is like this:
import { Module } from '@nestjs/common'; @Module({ imports: [AaaModule], controllers: [BbbController], providers: [BbbService], exports: [BbbService] }) export class BbbModule {}
Here, the Module of Bbb is declared through the decorator of @ Module, which depends on the Aaa Module, that is, the aaaamodule introduced in imports. Controllers are controllers, including bbbcontrollers. Providers are providers, including service, factory and other types. BbbService is included here. At the same time, BbbService is exported and can be introduced by other modules.
The Controller is also declared through the decorator:
@Controller() export class BbbController { }
The declaration of Service is also a decorator, but it is not called Service, but Injectable.
@Injectable() export class BbbService { }
As for why it is called Injectable, it involves the concept of IOC.
IOC (reverse of control) means control inversion, which means that you only need to declare your dependencies, and you don't need to create dependent objects. The container will inject them into you.
Because all objects are managed by the container, it is natural to inject the dependencies it needs when creating objects. This is the principle of IOC.
Service can be injected into instances of other classes as dependencies, so use the Injectable decorator.

All modules will have a root Module as the entry. Starting the IOC container starts from this Module:
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import "reflect-metadata"; async function bootstrap() { const app = await NestFactory.create(AppModule); await app.listen(3000); } bootstrap();
Above is a typical nest JS startup code, create an IOC container from the root Module AppModule to process requests sent from port 3000.
The reflect metadata module is used to resolve the decorator of a class, because to inject dependencies into an instance of a class, you must be able to resolve which dependencies it declares through the decorator, and then inject them into it. Therefore, to implement IOC, you need to rely on this package.
This is nest JS roughly designs: IOC + MVC, manages object dependencies through IOC container, and divides responsibilities through Controller, Service and Module.
Nest.js combined with Typeorm
Typeorm synchronizes the operation of objects to the orm of database operation through sql, while nest JS is used for MVC layering of Web back-end applications and managing the creation and dependency of objects through IOC. These two can be combined naturally. The way of combination is @ nestjs/typeorm package.
@The nest JS / typeorm package provides the TypeOrmModule, which has two static methods forRoot and forFeature.
forRoot is used to create a database connection. Pass in some configuration parameters and import them in the entry Module.
@Module({ imports: [ TypeOrmModule.forRoot({ type: 'mysql', host: 'localhost', port: 3306, username: 'root', password: 'Your password', database: 'Database name', synchronize: true }), NotesModule ] }) export class AppModule {}
forFeature is used to create a Repository corresponding to different entity classes and is introduced in the Module using the entity.
@Module({ imports: [TypeOrmModule.forFeature([Aaa])], controllers: [AaaController], providers: [AaaService], exports: [AaaService] }) export class AaaModule {}
We know Typeorm and nest What does JS do and how to use it? A brief summary:
Typeorm is an ORM framework, which is used to synchronize the operation of objects to the operation of the database, and will automatically execute sql statements.
Nest.js is an MVC framework, which is used for logical layering of Web back-end applications. It also provides a Module to further divide controllers and services. In addition, nest JS provides an IOC container to uniformly manage the creation and dependency of objects, and automatically inject dependencies according to declarations.
The combination of the two is through the package of @ nestjs/typeorm, which has two static methods for generating modules.
Having said so much, you may not understand it very clearly, so let's take a practical case of note management.
Actual combat cases
Nest. There are a lot of JS template code, and it's a lot of trouble to write it yourself. The command line tool of @ nestjs/cli automates these.
First, build the skeleton of the project and use
nest new project-name
Then generate the code of a Module
nest g resource xxx

The generated code is with Controller, Service and Module, and also has CRUD template code.
Let's focus on the following Controller codes:
import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; import { XxxService } from './xxx.service'; import { CreateXxxDto } from './dto/create-xxx.dto'; import { UpdateXxxDto } from './dto/update-xxx.dto'; @Controller('xxx') export class XxxController { constructor(private readonly xxxService: XxxService) {} @Post() create(@Body() createXxxDto: CreateXxxDto) { return this.xxxService.create(createXxxDto); } @Get() findAll() { return this.xxxService.findAll(); } @Get(':id') findOne(@Param('id') id: string) { return this.xxxService.findOne(+id); } @Patch(':id') update(@Param('id') id: string, @Body() updateXxxDto: UpdateXxxDto) { return this.xxxService.update(+id, updateXxxDto); } @Delete(':id') remove(@Param('id') id: string) { return this.xxxService.remove(+id); } }
@The Controller parameter can declare the URL path, @ get, @ Post, @ Patch, @ Delete, or the URL path through the parameter, which will eventually put the two together. For example, / xxx /: get method of ID.
@Get, @ Post, @ Patch, @ Delete correspond to different request methods.
@Param is the parameter in the Query path, @ Query is the parameter in the Query string.
@The Body sets the request parameters to the properties of the object. The object used to transfer data is called dto (data transfer object).
Then, the returned object will be serialized into JSON without manual serialization.
Then look at Service:
import { Injectable } from '@nestjs/common'; import { CreateXxxDto } from './dto/create-xxx.dto'; import { UpdateXxxDto } from './dto/update-xxx.dto'; @Injectable() export class XxxService { create(createXxxDto: CreateXxxDto) { return 'This action adds a new xxx'; } findAll() { return `This action returns all xxx`; } findOne(id: number) { return `This action returns a #${id} xxx`; } update(id: number, updateXxxDto: UpdateXxxDto) { return `This action updates a #${id} xxx`; } remove(id: number) { return `This action removes a #${id} xxx`; } }
The methods of these service s are not specifically implemented.
We introduce Typeorm as the CRUD of the database.
Introduce the Module for database connection in the root Module

Introduce the Module corresponding to the entity in the newly created Module:

Create a note Entity and identify it with @ Entity. And use @ Column and @ primarygenerated Column to identify the Column and primary key.
import { Entity, PrimaryGeneratedColumn, Column } from "typeorm"; @Entity() export class Note{ @PrimaryGeneratedColumn() id: number; @Column() title: string; @Column() content: string; @Column() createTime: Date; @Column() updateTime: Date; @Column() isDelete: boolean; }
Then inject the operation class Repository corresponding to the entity into the service to add, delete, modify and query the notes.

The dto used is the object corresponding to the parameter. They are a collection of attributes of an entity. For example, update dto:
export class UpdateNoteDto { title: string; content: string; createTime: Date; updateTime: Date; isDelete: boolean; }
In this way, the addition, deletion, modification and query of notes are realized.
We use postman to test the following effects:
Run npm start to get the project running

You can see that the route mapping of the four interfaces is successful.
The database starts with two records:

It can be found correctly through the query interface:

Then modify the interface under test:

The database has indeed been modified:

After testing, the CRUD function of the note sheet is normal.
We finished the first nest JS backend application!
The complete code is uploaded to GitHub: https://github.com/QuarkGluonPlasma/nestjs-exercize
summary
Typeorm is an ORM framework. Through the corresponding relationship between the mapping table and the object, you can convert the operation on the object into the operation on the database and automatically execute sql statements.
Nest.js is an MVC framework, which provides the logical division of Module, Controller and Service, and also implements the IOC mode to centrally manage objects and automatically inject dependencies.
Typeorm and nest JS uses @ nestjs/typeorm package in combination. It provides a Module of TypeormModule with two static methods: forRoot and forFeature. The forRoot method is used to generate the Module connecting to the database, and the forFeature is used to generate the Module of the Repository corresponding to the entity.
Nest.js has a lot of template code, which can be generated by @ nestjs/cli command-line tool, including the overall and each Module.
In short, if you understand the IOC and the division of Module, Controller and Service, even if you have a preliminary grasp of nest JS, combined with the ORM framework of Typeorm, you can easily do CRUD of database tables.