目录

1. 初识 Nest.js

1.1 什么是 Nest.js

1.2 Nest.js 优点

2. Nest.js 核心概念

2.1 控制器 Controller

2.2 提供者 Provider

2.3 模块 Module

2.4 中间件 Middleware

2.5 异常过滤器 Filter

2.6 管道 Pipe

2.7 守卫 Guard

2.8 拦截器 Interceptor

2.9 装饰器

2.10 路由

2.11 AOP(Aspect Oriented Programming)

3. Nest.js 内部层级关系

4. 对象属性中的特性值 vs 装饰器


1. 初识 Nest.js

1.1 什么是 Nest.js

用于构建 高效 / 可伸缩的服务端应用程序的 渐进式 Node.js 框架

1.2 Nest.js 优点

  1. 支持 TypeScript,使语法更加规范
  2. 兼容 Express 中间件,Express 是最早出现的轻量级的 node server端框架
  3. 层层处理,可以约束代码,比如何时使用中间件、使用 Guards守卫 等
  4. 依赖注入及模块化的思想,提供了完整的 MVC 链路,使代码结构清晰,便于维护

2. Nest.js 核心概念

2.1 控制器 Controller

客户端的请求,最终交给 哪个函数 / 模块 ,都需要通过预先处理,直接处理客户端请求(路由、方法等)的模块,称之为 控制器

控制器原理:

  1. 控制器 —— 接收应用的特定请求
  2. 路由机制 —— 控制哪个控制器接收哪些请求
  3. 控制器及路由的关系 —— 一个控制器有多个路由,不同路由 执行 不同操作

2.2 提供者 Provider

几乎所有的东西都可以被认为是提供者(例如:service, repository, factory, helper...),提供者的本质:用 @Injectable() 装饰器 注解的简单类

提供者 Provider 可以通过 constructor 注入依赖关系(即创建各种关系)

【控制反转】是面向对象编程中的一种 设计原则,用来降低代码耦合度

通过控制反转,对象在被创建的时候,有一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它

也可以说,通过控制反转,依赖被注入到对象

【依赖注入】把有依赖关系的类放到容器中,解析出这些类的实例,进而实现类的解耦

举个栗子:Class A 中用到了 Class B 的对象 b,一般情况下,需要在 A 的代码中显式的 new 一个 B 的对象。采用依赖注入技术之后,A 的代码只需要定义一个私有的 B 对象,不需要直接 new 来获得这个对象,而是通过相关的容器控制程序来将 B 对象在外部 new 出来并注入到 A 类里的引用中

【控制反转和依赖注入的关系】

  • 依赖注入(Dependency Injection,简称 DI)
  • 控制反转(Inversion of Control,简称 IoC)

DI 是实现 IoC 的一种常见方式

举个栗子(摘抄):假设你是一个想开公司的富二代,开公司首先需要一间办公室。那么你不用自己去买,你只需要在你的清单列表上写上办公室这么一项,那么,你老爸已经派人给你安排好了办公室,这间办公室长什么样?多大?在哪里?是租的?还是买的?你根本不知道,你也不需要知道。 现在你又在清单上写了需要 80 台办公电脑,你老爸又给你安排好了 80 台, 你自己并不需要关心这些电脑是什么配置,买什么样的 CPU 性价比更高,只要他们是能办公的电脑就行了。

这里你的老爸就是所谓的 IoC 容器,你在编写 Company 这个 Class 的时候,你内部用到的 Office、Computers 对象不需要你自己导入和实例化,你只需要在 Company 这个类的 Constructor (构造函数) 中声明你需要的对象,IoC 容器会帮你把所依赖的对象实例注入进去。

Nest 就是建立在 依赖注入 这种设计模式之上的

它在框架内部封装了一个 IoC 容器来管理所有的依赖关系

2.3 模块 Module

模块是用 @Module() 装饰器 注解的简单类

@Module() 装饰器提供了 元数据,Nest 用它来 组织应用程序结构

每个 Nest 应用程序至少有一个模块 —— 根模块

  • 当应用很小时,根模块可能是应用程序中唯一的模块
  • 当应用很大时,应用将会拥有多个模块,每个模块都有一组紧密相关的功能

模块的好处:业务低耦合、边界清晰、便于排查错误、便于维护

@module() 装饰器接受一个 描述模块属性的对象

@Module({providers: [UserService],controllers: [UserController],imports: [OrderModule],exports: [UserService],
})
export class UserModule {}
  • providers:服务提供者列表,本模块可用,会自动注入
  • controllers:控制器列表,本模块可用,会绑定路由访问
  • imports:本模块导入的模块,如需要使用其他模块的 provider,则必须导入其他模块
  • exports:本模块导出的服务提供者,在此处定义的 provider 才能被其他模块使用

2.4 中间件 Middleware

中间件 —— 客户端 和 路由处理 的中间,在路由处理程序之前,调用的 函数

中间件函数可以访问:请求对象、响应对象、请求响应周期中的 next() 中间件函数

next() 中间件函数,通常由名为 next 的变量表示,他决定了请求-响应的循环系统

Nest 中间件,可以是一个函数,也可以是一个带有 @Injectable() 装饰器 的类

【中间件函数的任务】

  1. 执行任何代码
  2. 对请求和响应对象进行更改
  3. 结束请求-响应周期
  4. 调用堆栈中的下一个中间件函数
  5. 如果当前中间件函数,没有结束 请求-响应周期,它必须调用 next() 将控制传递给下一个中间件函数,否则,请求将被挂起

2.5 异常过滤器 Filter

当项目中出现了异常,而代码中却没有处理,那么这个异常就会到 Nest.js 内建的异常处理层,它能将异常更友好地响应给前端

当异常无法识别时 (既不是 HttpException 也不是继承 HttpException 的类 ) , 将会收到以下 JSON 响应:

{"statusCode": 500,"message": "Internal server error"
}

2.6 管道 Pipe

管道本质:一个实现了 PipeTransform 接口,并用 @Injectable() 装饰器 修饰的类

管道作用:

  1. 转换:将输入数据转换为所需的格式输出
  2. 验证:验证输入的内容是否满足预先定义的规则,当数据不正确时可能会抛出异常

举个栗子:把参数转化成十进制的整型数字 的管道 ParseIntPipe

// 注意下方 使用的装饰器 @Injectable() 及 实现的接口 PipeTransform
@Injectable()
export class ParseIntPipe implements PipeTransform<string, number> {transform(value: string, metadata: ArgumentMetadata): number {const val = parseInt(value, 10);if (isNaN(val)) {throw new BadRequestException("Validation failed");}return val;}
}

对于 get 请求中的参数 id,调用 new ParseIntPipe 将 参数 id 转化成十进制的整数

@Get(':id')
async findOne(@Param('id', new ParseIntPipe()) id) {return await this.catsService.findOne(id);
}

2.7 守卫 Guard

守卫:实现权限验证,比如验证请求是否包含 token 或者 token 是否过期

与 中间件 Middleware 相比,守卫 Guard 能获得更详细的关于请求的执行上下文信息

通常 Guards,位于 Middleware 之后,Pipe 之前(请求正式被处理函数处理之前)

import { Injectable, CanActivate, ExecutionContext } from "@nestjs/common";
import { Observable } from "rxjs";@Injectable()
export class AuthGuard implements CanActivate {canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {const request = context.switchToHttp().getRequest();return validateRequest(request);}
}
export interface ArgumentsHost {getArgs<T extends Array<any> = any[]>(): T;getArgByIndex<T = any>(index: number): T;switchToRpc(): RpcArgumentsHost;switchToHttp(): HttpArgumentsHost;switchToWs(): WsArgumentsHost;
}
export interface ExecutionContext extends ArgumentsHost {getClass<T = any>(): Type<T>;getHandler(): Function;
}

2.8 拦截器 Interceptor

拦截器本质:一个实现了 NestInterceptor 接口,并用 @Injectable() 装饰器 修饰的类

拦截器作用:

  1. 在函数执行前/后,绑定额外逻辑
  2. 转换从函数返回的结果
  3. 转换从函数抛出的异常
  4. 重写函数

举个栗子:对所有接口返回的 数据结构 处理(应用拦截器的)

2.9 装饰器

装饰器 —— 一种特殊类型的声明,本质上就是一个 方法

装饰器可以注入到类、类的方法、类的属性、类的参数上,用于扩展功能

装饰器的分类:

  1. 类的装饰器
  2. 类方法的装饰器
  3. 类函数参数的装饰器
  4. 类的属性的装饰器

举个栗子:项目代码 main.ts 页面(应用装饰器)

2.10 路由

回顾:控制器 Controllar 用于接收应用程序的特定请求,基于 路由机制 来实现请求分发;每个控制器对应多个路由,不同的路由可以执行不同的动作

回顾:路由映射(将请求绑定到相应的控制器)

【路由指向、全局路由前缀】 

以 src/main.ts 为例:

  • await NestFactory.create(AppModule) —— 使用 Nest 的工厂函数创建 AppModule
  • await app.listen(3000) —— 监听 3000 端口,可自定义
  • http://localhost:3000/thsapp/
    思考:thsapp 由来?输出结果的由来?—— 全局路由前缀
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';async function bootstrap() {// 使用 Nest 的工厂函数创建 AppModuleconst app = await NestFactory.create(AppModule);// 设置全局路由前缀app.setGlobalPrefix('thsapp'); // 全局路由前缀// 监听 3000 端口,可自定义await app.listen(3000);
}bootstrap();

【局部路由前缀】 

http://localhost:3000/thsapp/user
思考:use 由来?输出结果的由来?

import {Controller, Get} from '@nestjs/common';@Controller('user')
export class User2Controller {// http://localhost:3000/thsapp/user@Get()async getUserInfo() {return '我是用户信息';}// http://localhost:3000/thsapp/user/info// @Get('info')// async getUserInfo() {//   return '获取用户信息';// }
}
// src/app.controller.ts
import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.services';@Controller()
export class AppController {constructor(private readonly appService: AppService) {}@Get()getHello(): string {return this.appService.getHello();}
}
// src/app.service.ts
import { Injectable } from '@nestjs/common';@Injectable()
export class AppService {getHello(): string {return 'Hello World!';}
}

2.11 AOP(Aspect Oriented Programming)

面向切面编程 —— 通过 预编译方式 和 运行期间动态代理 实现程序功能的统一维护的一种技术(在运行时,动态地将代码切入到类的指定方法、指定位置上)

切入点:指定类/指定方法 切入到的 代码片段 称为切面,切入到哪些类、哪些方法

AOP 可以把几个类共有的代码,抽取到一个切片中,等到需要时再切入对象中去,从而改变其原有的行为

AOP 优点:

  1. 降低业务逻辑各部分之间的耦合度
  2. 提高程序的可重用性
  3. 提高了开发的效率
  4. 提高代码的灵活性和可扩展性

将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来

通过对这些行为的分离,将它们独立到非指导业务逻辑的方法中,进而实现改变这些行为时,不影响业务逻辑的代码

3. Nest.js 内部层级关系

4. 对象属性中的特性值 vs 装饰器

ES5 中,对象中的每个属性都有 特性值 来描述这个属性的特点,他们分别是:

  • configurable:属性是否能被 delete 删除,当值为 false 时,其他特性值也不能被改变,默认值为 true
  • enumerable:属性是否能被枚举,也就是是否能被 for in 循环遍历,默认为 true
  • writable:属性值是否能修改,默认为 true
  • value:属性值具体是多少,默认为 undefined
  • get:当通过 person.name 访问 name 的属性值时,get() 将被调用,get() 可以自定义返回的具体值是多少,get 默认值为 undefined
  • set:当通过 person.name = 'Jake' 设置 name 的属性值时,set() 将被调用,set() 可以自定义设置值的具体方式,set 默认值为 undefined

注意:不能同时设置value、writeable 与 get、set

可以通过 Object.defineProperty(操作单个)Object.defineProperties(操作多个)来修改这些特性值

上述方法的参数:

  • target(对象)
  • key(对象属性)
  • descriptor(对象属性的 特性值的 描述对象)
var person = {name: "Lily",
};// 修改
Object.defineProperty(person, "name", {value: "Lucy",
});// 新增
Object.defineProperty(person, "age", {value: 20,
});

下面写一个装饰器函数 nameDecorator()

函数 nameDecorator(),会重写被他装饰的属性,函数最后必须返回 descriptor

function nameDecorator(target, key, descriptor) {descriptor.value = () => {return "Tom";};return descriptor;
}

@nameDecorator,就是装饰器语法

自定义函数 nameDecorator 的参数中,target(被装饰的对象Person),key(被装饰的具体方法 getName())

getName() 方法的三个参数,与 Object.defineProperty 一一对应,分别指当前的对象Person,被作用的属性 getName(),以及属性特性值的描述对象 descriptor

函数 nameDecorator(),会重写被他装饰的属性 getName()

class Person {constructor() {this.name = "Lily";}@nameDecoratorgetName() {return this.name;}
}let p1 = new Person();
console.log(p1.getName());

Nest.js 名词概念介绍相关推荐

  1. 学完这篇 Nest.js 实战,还没入门的来锤我!(长文预警)

    大厂技术  高级前端  Node进阶 点击上方 程序员成长指北,关注公众号 回复1,加入高级Node交流群 前言 最近一直比较忙, 而且自己工作中做的事也不适合写文章,所以一直没有更文.. 最近接到一 ...

  2. Nest.js 从零到壹系列(六):用 15 行代码实现 RBAC 0

    本文由图雀社区认证作者 布拉德特皮 写作而成,点击阅读原文查看作者掘金链接,感谢作者的优质输出,让我们的技术世界变得更加美好???? 上一篇介绍了如何使用 DTO 和管道对入参进行验证,接下来介绍一下 ...

  3. Nest的基本概念,以及如何使用Nest CLI来构建一个简单的Web应用程序

    Nest是一个用于构建高效.可扩展的Node.js服务器端应用程序的框架.它是基于Express.js构建的,并且提供了多种新特性和抽象层,可以让开发者更加轻松地构建复杂的应用程序. 本文将介绍Nes ...

  4. js return 后 运行 另_新手入门Nest.js(六) 控制器Resources、路由通配符

    点击上方公众号,可快速关注 作者:鲲鹏友人原文链接:https://www.gowhich.com/blog/1067 Nest.js控制中的Resources 前面介绍了路由中如何通过GET方式访问 ...

  5. nestjs配置MySQL数据库,Nest.js 中的数据库操作

    安装 Typeorm 为了与 SQL 和 NoSQL 数据库集成,Nest.js 提供了@nestjs/typeorm 软件包.Nest.js 使用 TypeORM,因为它是 TypeScript 最 ...

  6. js 加入debug后可以进入controller_写给前端的 Nest.js 教程——10分钟上手后端接口开发

    前言 沉默了很久,一直都没发文章,有些惭愧. 最近实习结束之后回了学校,提前开始做毕业设计了.对,就是毕业设计. 近两个月把 React Native.Vue 3.0 和 Nest.js 都摸了一下, ...

  7. 区块链教程(二):基础概念介绍

    注:本教程为技术教程,不谈论且不涉及炒作任何数字货币 本系列重点在于以太坊基础知识.以太坊客户端以及以太坊solidity编程,因此博客重点在于以太坊核心知识点的掌握,区块链部分的基础知识可以作为补充 ...

  8. Linux内存管理之基本概念介绍(一)

    Linux内存管理之基本概念介绍(一) Linux内存管理之物理内存管理(二) Linux内存管理之内存管理单元(MMU)(三) Linux内存管理之分配掩码(四) Linux内存管理之伙伴系统(五) ...

  9. js 加入debug后可以进入controller_写给前端:让后端 CRUD Boy 失业—— Nest.js CRUD 教程

    前言 沉默了很久,一直都没发文章,有些惭愧. 最近实习结束之后回了学校,提前开始做毕业设计了.对,就是毕业设计. 近两个月把 React Native.Vue 3.0 和 Nest.js 都摸了一下, ...

最新文章

  1. 突然就懵了!面试官问我:线程池中多余的线程是如何回收的?
  2. 两台虚拟机的Putty端实现互相免密码登录
  3. obj + mtl 格式说明
  4. r语言的MASS包干什么的_R语言综述的包
  5. Nordic Collegiate Programming Contest (NCPC) 2016
  6. JavaScript算法(实例八)递归计算每个月的兔子总数【斐波那契数列】
  7. python自动回复机器人手机版_GitHub - HZQHZA/wxpy: Python 写 微信聊天 根据 自动回复 接入机器人 等等.......
  8. html 图片切换渐变效果图,CSS3 用CLIP来做图片切换的渐变效果
  9. vue 引入自定义js方法并调用
  10. 开源视频会议系统:OpenMeetings 安装方法
  11. 电脑知识 如何提取图片中的文字
  12. java测试脚本怎么写_Jmeter测试脚本编写(初学者熟悉篇)
  13. 使用EXCEL计算并绘制KDJ指标
  14. ADB识别失败,驱动显示感叹号解决方案——记录一次驱动重装导致的不识别手机问题
  15. ios上架应用在苹果商店搜不到
  16. debian8.7 下配置fai机环境
  17. Java自学经验分享
  18. 提高元认知能力时刻掌握方向舵主动控制生命航向
  19. 【推荐】javaweb JAVA JSP家政服务管理系统服务网站jsp服务信息管理jsp保姆月嫂招聘系统案例设计与实现源码
  20. SSH 官网下载地址

热门文章

  1. 【速度最快的浏览器】Chrome for Mac V75.0
  2. 同济大学2020计算机复试线,2020考研分数线 同济大学2020考研复试分数线什么时候公布...
  3. 理解java代理模式
  4. 绝杀慕尼黑_慕尼黑如何将15,000台PC从Windows切换到Linux
  5. 震旦adc218网络ip设置方法
  6. 企业决策智能项目的五种失败姿势
  7. 一款能生成NC文件(雕刻路径文件)的 inkscape ,想必很多人都找不到能用的
  8. python 保存和读取中间变量
  9. 中秋两款数字藏品免费空投,手慢无
  10. vue中使用element-tiptap富文本编辑器