Nest
基本路由
路由是指确定应用程序如何响应客户端对特定端点的请求,该端点是 URI
(或路径)和特定的 HTTP
请求方法(GET、POST
等)。
第一个 Nestjs
项目
使用 Nest CLI
创建第一个 Nestjs
项目 hello-world
nest new hello-world
安装时,您将看到以下提示:
等待一段时间,脚手架会创建一个初始项目结构,生成初始的项目文件模板。
平台
Nestjs
现成支持的两个 Nodejs
平台:Express和fastify
。Nestjs
默认使用 Express
作为基础的支持框架。
在 main.ts
中,NestFactory.create(AppModule)
创建的 App
实例,可以传递类型指明使用的平台,理论上来说,只要创建了适配器,Nest
可以和任何 node.js
的 HTTP
框架一起工作,比如 fastify
实现了 FastifyAdapter
,那么就可以在 Nest
中使用它了。
INFO
NestExpressApplication
由@nestjs/platform-express
导出NestFastifyApplication
由@nestjs/platform-fastify
导出
运行
安装完成后,在终端运行以下命令,启动 Nest
应用程序:
npm run start
此命令启动 HTTP
服务监听定义在 src/main.ts
文件中定义的端口号。在应用程序运行后, 打开浏览器并访问 http://localhost:3000/
。 你应该看到 Hello world!
。
要持续监听文件的修改,自动重新编译并重新加载服务器,可以运行以下命令来启动程序:
npm run start:dev
创建一个 Nest
应用
每个 Nest
应用是通过 NestFactory.create
方法创建的新的应用实例,每次调用需要传递一个根模块,其他的模块作为其子模块。
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(3000);
}
打开 AppModule
,根模块提供了用来启动应用的引导机制,可以包含很多功能模块。
providers:
Nest.js
注入器实例化的提供者(服务提供者),处理具体的业务逻辑,各个模块之间可以共享(注入器的基础概念在Nest
设计模式会学习,以及后续补充提供者的概念);controllers:处理http请求,包括路由控制,向客户端返回响应,将具体业务逻辑委托给providers处理;
imports:导入模块的列表,如果需要使用其他模块的服务,需要通过这里导入;
exports:导出服务的列表,供其他模块导入使用。如果希望当前模块下的服务可以被其他模块共享,需要在这里配置导出;
第一个 HelloWorld
程序,完全按照前后端分离的 MVC
模式来编写的。接触过 Java
的读者就会感到熟悉,Nestjs
和 Spring MVC
长得非常相似。
Controller
:传统意义上的控制器,提供 api 接口,负责处理路由、中转、验证等一些简洁的业务;Service
:又称为Provider
, 是一系列服务、repo、工厂方法、helper 的总称,主要负责处理具体的业务,如数据库的增删改查、事务、并发等逻辑代码;Module
:负责将Controller
和Service
连接起来,类似于namespace
的概念,你可以把模块看做一个“封闭的盒子“,控制器看做盒子的入口,服务提供者看做盒子里的工具。封闭也就意味着如果不向外界提供服务,外界的模块无法使用封闭的盒子的工具,这就是提供其他模块使用的服务,要在exports
中导出的原因。
新增模块
通过新增 User
模块来进行实战,模拟用户发送请求获取数据的操作。
使用 Nest CLI
提供的命令可以快速生成文件:
nest g res user --no-spec
如果不知道命令的话,可以使用以下命令查询或者去 用法-CLI 查看:
nest --help
脚手架会帮我们生成文件,并将 User
模块自动注册,注入到根模块的 imports
数组中。
@Module({
imports: [UserModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Module
使用指令创建文件,Nest CLI
自动生成相关文件,并将它们完成注册。
@Module({
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
如果选择手动创建,我们也只需要按照上面的格式,将服务、控制器注入到模块,并将定义好的模块导入到 AppModule
的 imports
数组中即可。
Controller
最初的控制器只有一个 @Controller
装饰器,接下来我们需要在 UserController
中填充路由方法。@Controller
传递一个 path
参数,作为该控制器的路由前缀
import { Controller } from '@nestjs/common';
@Controller('user')
export class UserController {}
在控制器中使用 请求方法 的装饰器并填充路由。
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
findAll(): any[] {
// ...
}
}
@Get
装饰器表示当前的 findAll
是只能通过 Get
请求才能访问的方法。
Service
接下来我们需要填充业务方法 UserService.findAll
。(这里用 Mockjs
模拟数据返回)
import { Injectable } from '@nestjs/common';
import * as Mock from 'mockjs';
@Injectable()
export class UserService {
findAll() {
return Mock.mock({
'list|10': [
{
'id|+1': 1,
name: '@cname',
email: '@email',
},
],
});
}
}
打开浏览器输入 http://localhost:3000/user
进行访问,出现以下结果,表示模块新增完成: