Nest 采用模组化设计,将各个不同的功能区块打包成 模组 (Module),而 Module 必定有 一个以上,并且是以 树状结构 发散出去,最顶部的 Module 称为 根模组 (Root Module),其概念如下:
而一个 有路由机制 的 Module 会带有 控制器 (Controller) 与 服务 (Service),它们之间的关系如下:
从图中可以看出 Controller 与 Service 透过 Module 建立关系後,即可将 Service 注入 (Inject) 到 Controller 中使用,这样的好处是可以职责分离,把处理请求的操作交给 Controller,把处理逻辑的部分交给 Service,这样说明有点太抽象了,那来点实际流程吧:
用现实生活中的例子来说明 Nest 整体概念的话,Nest App 就像一间有多国料理的餐厅,该餐厅规划每种国家的料理即一个区块,每个区块都有负责的外场服务生,而这个区块即为 Module,Controller 就是外场服务生,而 Service 则是内场人员,当客人走进餐厅时,先依照想吃的异国料理来安排座位,外场服务生协助客人点餐并将订单送至内场,内场人员开始针对客人的订单做料理,当餐点做好了之後,再请外场服务生送到客人面前:
现在对於 Nest 应该有些概念了,那就来看怎麽建置第一个 Nest App 吧!
Nest 官方设计了一套 CLI 来帮助各位开发者们加速开发,可以透过 NestCLI 自动产生程序码骨架,这样一来便可以大幅降低「相同操作重复做」的次数,非常贴心。那要如何安装呢?只需要透过 npm
进行全域安装即可,在终端机输入下方指令:
$ npm install -g @nestjs/cli
安装完以後就可以透过终端机使用 NestCLI 了,查看有哪些指令可以使用:
$ nest --help
透过 NestCLI 的 new
指令来快速建立 App:
提醒:注意终端机当前位於资料夹何处,建议透过 cd 指令移动到想要的位置。
$ nest new <APP_NAME>
此时会建立一些 App 的骨架,并询问要使用哪种套件管理程序:
提醒:这里可以根据个人喜好选择,笔者这边选 npm。
等程序跑完後,就来执行看看吧:
$ cd <APP_NAME>
$ npm start
Nest 预设是在 3000 port,从浏览器网址列输入 http://localhost:3000 来看架设结果:
透过 NestCLI 建置的专案资料夹结构如下:
.
├─ dist
├─ node_modules
├─ src
| ├─ app.controller.ts
| ├─ app.controller.spec.ts
| ├─ app.module.ts
| ├─ app.service.ts
| └─ main.ts
├─ test
| ├─ app.e2e-spec.ts
| └─ jest-e2e.json
├─ .eslintrc.js
├─ .gitignore
├─ .prettierrc
├─ nest-cli.json
├─ package.json
├─ package-lock.json
├─ tsconfig.json
├─ tsconfig.build.json
└─ README.md
npm install <PACKAGE>
所安装的档案。tsconfig.json
的延伸。注意:这边会简单带过,後续会再针对各功能做详细的说明。
在 src
资料夹中,撇除测试用的 app.controller.spec.ts
外,会看到 main.ts
、app.module.ts
、app.controller.ts
以及app.service.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();
以非同步的 bootstrap
函式做为载入函式,透过 NestFactory.create(AppModule)
产生一个 Nest App 的实例 (Instance),并透过呼叫该实例的 listen(PORT)
将其架设起来。
提醒:PORT 即为要使用的 port,预设为 3000。
app.module.ts
为根模组,程序码如下:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
@Module({
imports: [],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
在 Nest 中,大部分的元件都是使用 装饰器 (Decorator) 的方式来提供 元数据 (Metadata),可以看到定义了一个名为 AppModule
的 class
,透过装饰器将其变成 Nest 的 Module,并在这里定义该模组的 Controller 与 Service。
app.controller.ts
是注册於根模组底下的 Controller, 不是必要项目。程序码如下:
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get()
getHello(): string {
return this.appService.getHello();
}
}
可以看到也是使用带有装饰器的 class
,比较特别的是里面的方法 (Method) 也使用了装饰器,来定义该方法是使用哪种方式进行触发等。另外,可以在 constructor
中看见 appService
的参数,这是使用 依赖注入(Dependency Injection) 的方式将 AppService
注入到 AppController
中。
app.service.ts
是注册於根模组底下的 Service,不是必要项目。程序码如下:
import { Injectable } from '@nestjs/common';
@Injectable()
export class AppService {
getHello(): string {
return 'Hello World!';
}
}
与 Module、Controller 有些不同,Service 所使用的装饰器为 Injectable
,原因是 Service 属於 抽象 的概念,在 Nest 中有许多抽象概念可以使用 Injectable
来实作,他们统一归类为 Provider。
Nest 提供高度的模组化设计,只要把 Controller 与 Service 定义好并放入对应的 Module 里,再像拼拼图一样把相关模组各自关联起来,就可以建立起易维护、低耦合、易扩展的 Node.js 後端应用,如果再使用官方设计的 NestCLI,将大幅加速开发时间!
其实 ISO 系统都是通用的,从 ISO 9001、 ISO 14001、 ISO 50001、IS...
物件复制: 浅层复制(shallow copy):仅被复制的一方能保留第一层的物件之值,但是当复制方...
这是一小段泡沫排序法的程序码,可是在说什麽呢?你可以试着阅读他,但千万不要勉强自己。 int mai...
昨天我们完成了一个基本的购物流程,但程序码内有着不安全的问题,今天我们要用 .env 的形式来规避这...
在设置关键字的时候,有些 NG 行为是不能犯的,今天就想跟大家聊聊,当我们在揣测消费者的心思时,哪些...