Nest 是一个用于构建高效,可扩展的 Node.js
服务器端应用程序的框架。在底层,Nest 使用强大的 HTTP Server 框架,如 Express(默认)和 Fastify。Nest 在这些框架之上提供了一定程度的抽象,同时也将其 API 直接暴露给开发人员。这样可以轻松使用每个平台的无数第三方模块。
支持 TypeScript
(也支持纯 js 编写代码),默认支持最新的 ES6 等语法和特性(用 babel 做代码转换)。node 版本要求 >= 10.13.0, v13 版本除外
。
要了解 Nest ,建议先了解一下装饰器,因为 Nest 里面的方法很多都是以装饰器的方式提供的,下面我简单介绍一下。已经了解的朋友可以跳过~
装饰器(Decorator)
是一种与类(class)
相关的语法,用来注释或修改类和类方法。它是一种函数,写成@ + 函数名
的形式。它可以放在类和类方法的定义前面。
@testable
class MyTestableClass {
// ...
}
function testable(target) {
target.isTestable = true;
}
MyTestableClass.isTestable // true
基本上,装饰器的行为就是下面这样。
@decorator
class A {}
// 等同于
class A {}
A = decorator(A) || A;
也就是说,装饰器是一个对类进行处理的函数。装饰器函数的第一个参数,就是所要装饰的目标类。
安装使用这里就不说了,可以到官网按照其引导来进行:https://docs.nestjs.com/first-steps。
生成的核心文件结构为:
src
|-app.controller.spec.ts
|-app.controller.ts
|-app.module.ts
|-app.service.ts
|-main.ts
其代表的含义分别为:
文件 | 含义 |
---|---|
app.controller.spec.ts | 控制器的单元测试 |
app.controller.ts | 控制器逻辑文件,通常含多个路由 |
app.module.ts | 应用程序的根模块 |
app.service.ts | 服务文件 |
main.ts | 应用程序的入口文件,它是基于NestFactory创建的一个Nest应用程序实例 |
什么是 Controller
?语义化翻译就是 控制器
,它负责处理传入的请求并将响应结果返回给客户端。
在 Nest
中,控制器和路由机制是结合在一起的,控制器的目的是接收应用程序的特定请求。其路由
机制控制哪个控制器接收哪些请求。通常,每个控制器都有多个路由,不同的路由可以执行不同的操作。
我们通过装饰器 @Controller()
来将一个类定义为控制器,如:
import { Controller } from '@nestjs/common';
@Controller('test')
export class TestController { }
Nest 把各个HTTP的请求方法都封装成了装饰器,如@Get()、@Post()、@Put()、@Patch()、@Delete()、@Options()
等,因此我们在实际开发中,可以直接用来装饰对应的请求,比如以下几种路由:
import { Controller, Get, Post, Body, Put, Param, Delete } from '@nestjs/common';
@Controller('test')
export class TestController {
@Post()
async create(@Body() createTestDto: CreateTestDto) {
return 'This action adds a new test';
}
@Delete(':id')
async remove(@Param('id') id) {
return `This action removes a #${id} test`;
}
@Put(':id')
async update(@Param('id') id, @Body() updateTestDto: UpdateTestDto) {
return `This action updates a #${id} test`;
}
@Get(':id')
async findOne(@Param('id') id) {
return `This action returns a #${id} test`;
}
}
什么是 Provider
?语义化翻译就是 提供者
,在 Nest 中,除了控制器以外,几乎所有的东西都可以被视为提供者,比如service、repository、factory、helper
等等。他们都可以通过构造函数注入依赖关系,也就是说,他们之间可以创建各种关系。而提供者只不过是一个用 @Injectable()
装饰器的简单类。
在类声明上,定义 @Injectable()
装饰器,即可将该类定义为提供者。如:
import { Injectable } from '@nestjs/common';
@Injectable()
export class TestService {
private readonly test: Test[] = [];
async create(createTestDto: CreateTestDto) {
this.test.push(createTestDto);
}
async remove(id: number) {
this.test.splice(test.indexOf(test.find(t => t.id === id)), 1);
}
async update(id: number, updateTestDto: UpdateTestDto) {
if(updateTestDto.name) this.test.find(t => t.id === id).name = updateTestDto.name;
}
async findOne(id: number): Test {
return this.test.find(t => t.id === id);
}
}
Module也是一个装饰器,Nest 使用 Module
来组织应用程序结构,每个应用程序至少有一个模块,即根模块。根模块是 Nest 开始排列应用程序树的地方。当应用程序很小时,根模块可能是应用程序中唯一的模块。不过,大多数情况下,都有很多模块,每个模块都有一组与其密切相关的功能。
模块,是用来组织 Controller
和 Provider
,为他们在 同模块范围内
建立依赖关系的。比如上面的 Controller
和 Provider
,我们建立关系:
import { Module } from '@nestjs/common';
import { TestController } from './test.controller';
import { TestService } from './test.service';
@Module({
controllers: [TestController],
providers: [TestService],
})
export class TestModule {}
只有这样,Nest 才可以在 TestController
中通过其构造函数,依赖注入 TestService
,才可以在 controller 中调用 service 服务。
而当不同模块之间的服务需要互相调用时,我们就要在对应的模块之间导出和导入了,例如:
import { Module } from '@nestjs/common';
import { TestController } from './test.controller';
import { TestService } from './test.service';
@Module({
imports: [],
controllers: [TestController],
providers: [TestService],
exports: [TestService]
})
export class TestModule {}
如果你必须在很多地方都导入相同的模块,这会出现大量的冗余。但是 Nest 将提供者封装在模块范围内,如果不导入模块,就无法在其他地方使用他们导出的提供者。但是有时候,你可能只是想提供一组随时可用的提供者,例如:helpers、database connection
等等。针对这种特殊情况,Nest 提供了一个很强大的功能 —— 全局模块
,全局模块一旦被导入到根模块,在其他所有模块中即可轻松的使用这个全局模块导出的提供者,而且也不用在其他模块导入这个全局模块。
将一个模块定义为全局模块,只需要在类上额外增加一个装饰器 @Global()
即可,示例:
import { Module, Global } from '@nestjs/common';
@Global()
@Module({
imports: [],
controllers: [],
providers: [],
exports: []
})
export class TestModule {}
Nest 模块系统有一个称为动态模块的特性。它能够让我们创建可定制的模块,当导入模块并向其传入某些选项参数,这个模块根据这些选项参数来动态的创建不同特性的模块,这种通过导入时传入参数并动态创建模块的特性称为 动态模块
。
@Module({})
export class AppModule {
static register(CustomController): DynamicModule {
return {
module: AppModule,
controllers: [CustomController],
providers: [],
exports: [],
};
}
}
在 Nest 中,我们通过在 main 入口中调用 NestFactory.create
来创建 Nest 应用实例,Nest 创建的实例默认是 express
实例。main 入口示例:
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
async function bootstrap() {
// 使用 NestFactory 创建一个根模块为 AppModule 的 Nest app
const app = await NestFactory.create(AppModule);
// 将这个 Nest app 监听本地的 3000 端口,即:http://localhost:3000
await app.listen(3000);
}
bootstrap();
Middleware 即中间件,它是请求发出者和路由处理器之间的桥梁,可以透明的、轻松的访问请求和响应对象。在 Nest 中,中间件可以有多个,他们之间使用 next()
方法作为连接,连接后的所有中间件将在整个请求-响应周期内通过 next()
依次执行。
注:默认情况下,Nest 中间件等同于 Express 中间件。Nest 中间件可以是一个函数,也可以是一个带有
@Injectable()
装饰器的类,且该类应该实现 NestMiddleware 接口,而函数没有任何特殊要求。如下简单示例:
// 带有 `@Injectable()` 装饰器的类中间件
import { Injectable, NestMiddleware } from '@nestjs/common';
@Injectable()
export class OAAuthMiddleware implements NestMiddleware {
use(req: Request, res: Response, next: NextFunction) {
console.log('Request...: ', req);
next();
}
}
// 函数中间件
export function OAAuthMiddleware(req, res, next) {
console.log('res: ', res);
next();
}
与Provider
和Controller
一样,中间件也能够通过构造函数注入属于同一模块的依赖项。
为了将中间件一次性绑定到每个注册的路由,我们可以通过 Nest 实例中的 use()
方法使用:
const app = await NestFactory.create(ApplicationModule);
// 这里必须使用函数中间件
app.use(OAAuthMiddleware);
await app.listen(3000);
既然中间件是请求发出者和路由处理器之间的桥梁,那么他就应该在一个模块的入口,即 XXXModule
类中被使用。在 Nest 中,我们只需要在模块类中实现 NestModule 接口:
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { OAAuthMiddleware } from './common/middlewares/oAAuthMiddleware.middleware';
import { TestModule } from './test/test.module';
@Module({
imports: [TestModule],
})
export class ApplicationModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(OAAuthMiddleware)
.forRoutes('test');
}
}
在上面的例子中,我们为 /test
路由处理器 (@TestController('/test'))
设置了鉴权中间件。如果只需要给 /test
路由中的某几个请求方法设置这个中间件,那只需要改变一下 forRoutes()
方法中的参数即可:forRoutes({ path: 'test', method: RequestMethod.GET })
,此时,只有 GET 请求才会被中间件拦截。如果存在很多路由规则,也可以使用通配符来处理。如:
forRoutes({ path: 'ab*cd', method: RequestMethod.ALL })
而当你想排除一个控制器类中的某些路由不使用中间件时,使用 exclude()
方法即可,如:
import { Module, NestModule, MiddlewareConsumer } from '@nestjs/common';
import { OAAuthMiddleware } from './common/middlewares/oAAuthMiddleware.middleware';
import { TestModule } from './test/test.module';
@Module({
imports: [TestModule],
})
export class ApplicationModule implements NestModule {
configure(consumer: MiddlewareConsumer) {
consumer
.apply(OAAuthMiddleware)
.exclude(
{ path: 'test', method: RequestMethod.GET },
)
.forRoutes('test');
}
}
了解了 Nest 的基本概念之后,可以安装@nestjs/cli
来体验一下 Nest 项目,这里给大家出个思考题,如何把 Nest 项目抽离为 runtime(Nest框架) + faas(入口文件) 的形式呢?
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/86Zo2ZEGqqZhxSccy9AToQ
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。