最近在开发新的 web 项目, 在选型时, 决定做 TS 的全栈开发, 用 NestJS+TypeORM+Vue3.0 开发. 在学习与开发过程中形成了自己对 NestJS 的理解, 因此有了这篇文章, 以前只用过 express, eggJS 开发, 并没有用过 NestJS, 如果有错误或不同的理解, 请指出, 谢谢~,那么开始进入正题吧~
安装开发环境软件
安装 NodeJS(>= 10.13.0, v13 版本除外
安装 Nest CLI
npm i -g @nestjs/cli
安装完后, 我们用以下命令看看有什么指令可以操作
nest -h
可以从上图知道以下操作指令
- nest new 名称 快速创建项目
- nest g res 名称 快速创建增删改查资源
- nest g co 名称 快速创建控制器
- nest g s 名称 快速创建服务
- nest g mi 名称 快速创建中间件
- nest g pi 名称 快速创建管道
- nest g mo 名称 快速创建模块
- nest g gu 名称 快速创建守卫
注意: 默认是当前目录, 如果创建到别的目录, 后面带上地址
创建项目
nest new my-project
安装依赖包文件
npm install
scr 目录内容有
src
├── app.controller.spec.ts
├── app.controller.ts
├── app.module.ts
├── app.service.ts
└── main.ts
main.ts 是入口文件
/* main.ts */ import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
bootstrap();
NestFactory 核心类, create() 方法加载 Module 文件, listen 监听 3000 端口启动.
运行
npm run start
这时打开 http://localhost:3000/。 你应该看到 Hello world!
我们可以在 app.module.ts 写组合文件, 在 app.controller.ts 写 API 接口, 在 app.service.ts 写业务逻辑或与数据库的交互.
NestJS 结构分析 模块(Module)
NestJS 是通过模块(module)文件组织应用程序结构.
从上图中可以看到 main.ts 入口文件里, 加载了 app.module.ts, 这个根模块. 然后 app.module.ts 文件里面又可以从 imports 加载其它部分的模块.
模块是具有
@Module()装饰器的类
providers由 Nest 注入器实例化的提供者,并且可以至少在整个模块中共享controllers必须创建的一组控制器imports导入模块的列表,这些模块导出了此模块中所需提供者exports由本模块提供并应在其他模块中可用的提供者的子集。
import { Module } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
import { CommonModule } from './common.module';
@Module({
imports: [CommonModule], // 引入其它模块
controllers: [CatsController], // API 接口
providers: [CatsService], // 给这模块里面的其它成员提供注入服务, 如 CatsController
exports: [CatsService] // 共享给别的模块使用
})
export class CatsModule {}
由于循环依赖性,模块类不能注入到提供者中 如果需要全局使用, 加入
@Global()装饰器就行.
MVC 框架
在说控制器前, 简单了解一下 MVC 设计模式.实际上,我们用到 MVC 设计模式去开发
MVC 就是一种设计模式, View 需要的数据(现在一般通过 API 方式), 向 Controller 请求数据, Controller 接收到请求后, 向 Model 要数据, 通常是向数据库要数据, 经过 Model 层(可以看作 NestJS 里面的 Service(服务)、Repository(数据库访问)等)处理完后返回给 Controller.
控制器(Controller)
控制器负责处理传入的请求和向客户端返回响应。
@Controller()装饰器定义一个基本的控制器
- 装饰器的值就是路由地址, 比如:
@Controller('customers') - 路径前缀 customers 与装饰器
@Get('profile')组合会为 GET/customers/profile请求生成路由映射
上面的模块里面, 我们引入了相关的控制器, 这里就可以使用
mport { Controller, Get } from '@nestjs/common';
@Controller('customers')
export class CatsController {
@Get('profile')
findAll(): string {
return 'This action returns all customers';
}
}
控制器的详细用法, 这里就不唠叨了, 可以看这中文文档->控制器
提供者(Providers)
Providers 是 Nest 的一个基本概念。许多基本的 Nest 类可能被视为 provider - service, repository, factory, helper 等等。 他们都可以通过 constructor 注入依赖关系。 这意味着对象可以彼此创建各种关系,并且“连接”对象实例的功能在很大程度上可以委托给 Nest运行时系统。
Provider 只是一个用
@Injectable()装饰器注释的类
我们在使用提供者类前, 在模块的 providers 先加载到模块,
然后在 constructor 构造器方法里面引入就可以使用, 如下 CatsService
import { Controller, Get, Post, Body } from '@nestjs/common';
import { CreateCatDto } from './dto/create-cat.dto';
import { CatsService } from './cats.service';
import { Cat } from './interfaces/cat.interface';
@Controller('cats')
export class CatsController {
constructor(private catsService: CatsService) {}
@Post()
async create(@Body() createCatDto: CreateCatDto) {
this.catsService.create(createCatDto);
}
}
详情用法, 可以看文档 Providers
小结
到了这里, 我们基本上可以写上 API 接口了. 步骤如下:
- 使用 CLI 命令创建
nest g res [模块名], 这里就创建了控制器、提供者服务类、数据库 DTO 等. 当然手动创建文件也行, 记得加入文件到模块中去. - 在控制器中写接口路由, 接收路由参数等. 调用提供者服务类做业务逻辑
- 提供者服务类去增删改查数据库. 然后数据返回给控制器
当然上面还有数据库, 后面会讲到. 最简单的一个 api 接口编写流程就是这样了. 很多细节的东西, 还是过一篇文档比较好.