当前位置:网站首页>Nest.js 用了 Express 但也没完全用
Nest.js 用了 Express 但也没完全用
2022-07-26 00:05:00 【油墨香^_^】
Node.js 提供了 http 模块用于监听端口、处理 http 请求,返回响应,这也是它主要做的事情。
但是 http 模块的 api 太过原始,直接基于它来处理请求响应比较麻烦,所以我们会用 express 等库封装一层。
这一层做的事情就是给 request 和 response 添加了很多处理请求响应的方法,满足各种场景的需求,并且对路由做了处理,而且,也提供了中间件的调用链便于复用一些代码,这种中间件的调用链叫做洋葱模型。

但这一层没有解决架构问题:当模块多了怎么办,怎么管理?如何划分 Model、View、Controller?等等。
所以,用 Node.js 做后端服务时我们会再包一层,解决架构问题,这一层的框架有 eggjs(蚂蚁的)、midwayjs(淘宝的)、nestjs(国外的)。
nestjs 是其中最优秀的一个:


![]()
这一层的底层还是 express、koa 等,它只是在那些 http 框架的基础上额外解决了架构问题。
而且 nestjs 还有一点做的特别好,它不依赖任何一个 http 平台,可以灵活的切换。
那么 nestjs 是怎么做到底层平台的切换的呢?
想想 react 是怎么做到把 vdom 渲染到 canvas、dom、native 的?
定义一层统一的接口,各种平台的 render 逻辑实现这些接口。这种模式叫做适配器模式。
适配器模式是当用到第三方实现的某个功能时,不直接依赖,而是定义一层接口,让第三方去适配这层接口。这样任何一个适配了这层接口的方案都能集成,也能够灵活的切换方案。
Nest.js 对底层的 http 平台就是提供了一层接口(HttpServer),定义了一堆用到的方法:
![]()
因为 ts 的 interface 必须实现所有的方法才行,为了简化,又继承了一层抽象类 AbstractHttpAdapter,把需要实现的方法定义成 abstract 的。

然后 express 或者别的平台比如 fastify 只要继承这个适配器的类,实现其中的抽象方法,就能接入到 Nest.js 里:
比如 ExpressAdapter:

或者 FastifyAdapter:
![]()
这些逻辑分别放在 platform-express 和 platform-fastify 包里:

Nest.js 第一行代码是调用 create:

create 里就会选择一种 httpAdapter 来创建服务:

默认是 express:

这样,之后调用的 request 和 response 的方法最终就都是 express 的了。
比如在 controller 里可以用 @Request 装饰器来注入 reqeust 对象,就可以调用 reqeust 的各种方法。
import { Controller, Get, Request } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get()
findAll(@@Request() request: Request): string {
return 'This action returns all cats';
}
}如果你想调用一些接口之外的特定平台的方法的话,Nest.js 也支持,那就换用 @Req 来注入:
import { Controller, Get, Req } from '@nestjs/common';
@Controller('cats')
export class CatsController {
@Get()
findAll(@@Req() request: Request): string {
return 'This action returns all cats';
}
}这样注入的就是特定平台比如 express 的原生 request 对象,就可以直接用它的所有方法。
此外,如果真的要用 Express 平台的特定 api 的话,在 NestFactory.create 的时候可以指定对应的类型参数,这样就能做相应的类型提示和检查了:
![]()
但是这样就和特定平台耦合了,除非是确定不会切换平台,否则不建议这么做。
http 平台是这么做的,同理,websocket 平台也是这样的:
定义了一层统一的接口,通过适配器的方式分别接入 socketio 和 websocket,可以灵活的切换:
![]()
图解下 Nest.js 关于 http 、websocket 平台的处理:
![]()
总结
Node.js 提供了 http 模块用来监听端口、处理请求响应,但是它的 api 过于原始,所以我们会包一层,在 express 这一层提供更多好用的 request、response 的 api,但这层没解决架构问题,要引入 MVC、IOC 等架构,需要再包一层,用 Egg.js、Midway.js、Nest.js 这种更上层的后端框架,其中 Nest.js 是最优秀的。
Nest.js 在和底层 http 平台的整合上做了特殊的设计,利用适配器模式,提供一层接口,让底层平台去适配,这样就可以灵活的切换不同的 http 平台了。
但它也同样支持用特定平台的 api,比如 controller 里可以用 @Req 注入底层的 request 对象,创建容器的时候也可以传入对应平台的类型参数。
Nest.js 默认使用的是 Express,但说用了 Express 也不完全对,因为可以灵活的切换别的。这就是适配器模式的魅力。
边栏推荐
- Cherish time and improve efficiency
- Js理解之路:写一个比较完美的组合继承(ES5)
- The GUI interface of yolov3 (simple, image detection)
- Stack and queue - 150. Inverse Polish expression evaluation
- 06_ UE4 advanced_ Set up a large map using the terrain tool
- Binary tree - 617. Merge binary tree
- Getaverse, a distant bridge to Web3
- 回溯——77. 组合
- Unity—欧拉角,四元数
- Binary tree 101. Symmetric binary tree
猜你喜欢

Leetcode169 detailed explanation of most elements

二叉树——104. 二叉树的最大深度

07_ UE4 advanced_ MP value of firing fireball and mechanism of attacking blood deduction

用了MQ消息中间件后,我开始后悔了...

Solve the problem of rapid index bar extrusion

Sequence traversal II of leetcode107 binary tree

模块二作业

06_ue4进阶_使用地形工具设置大地图

matlab实时作出串口输出数据的图像

初阶C语言 - 分支语句(if、switch)
随机推荐
NVIDIA cudnn learning
Recent impressions about bull market and defi 2021-05-17
Weight file and pre training file of yolov3
bond网卡模式配置
Js理解之路:Js常见的6中继承方式
Leetcode shahutong series -- 63. Different paths II
The items of listview will be displayed completely after expansion
BOM browser object model
Binary tree -- 222. Number of nodes of a complete binary tree
Observer model of behavioral model
Solidity智能合约开发 — 3.2-solidity语法数组、结构体、映射
Binary tree - 404. Sum of left leaves
34-SparkSQL自定义函数的使用、SparkStreaming的架构及计算流程、DStream转换操作、SparkStreaming对接kafka和offset的处理
Compile live555 with vs2019 in win10
MySQL的DDL、DML和DQL的基本语法
寻找链表的中间节点
回溯——17. 电话号码的字母组合
YoloV4-tiny网络结构
Yes, UDP protocol can also be used to request DNS server
Leetcode question brushing series -- 931. Minimum sum of descent path