装饰器赋能-nestJs概念初识
2018-02-17 本文已影响0人
dapaer
猫眼郑志昊提出连接、赋能、破界是互联网下半场的创新法则。赋能这个词个人理解的意思是赋予更多的能力,创造更多的价值。例如技术赋能、数据赋能、运营赋能等等。
此次我们介绍的框架是nestJs,nestJs是一个利用装饰器赋能的MVC后端框架(nodeJs + Typescript)
WWH-WHAT-装饰器赋能
装饰器赋能指的是利用装饰器附加一些额外的属性给特定的类、方法或者属性,举个例子假如你有一把普通宝剑,这把宝剑的攻击力只有10,不过这把宝剑上有三个宝石镶嵌孔,可以将得到的宝石镶嵌上去增加宝剑的威力,如果此时主人翁有红、绿、蓝三个宝石分别可以增加攻击力10、20、30,如果将这些宝石都镶嵌上去那么这把宝剑就不是一把普通的宝剑,而是攻击力达到70的绝世好剑了,下图代码简单说明:
// 普通宝剑类
export class Sword {
power: number;
init(power: number): void {
this.power = power;
}
constructor() {
this.init(10)
}
showPower () {
console.log(`power is ${this.power}`)
}
}
let commonSword = new Sword();
commonSword.showPower(); // power is 10
// 红宝石装饰器
export function BlueJewel(target, key, descriptor) {
const method = descriptor.value;
let powerPlus = 10;
let ret;
descriptor.value = (...args) => {
args[0] += powerPlus;
ret = method.apply(target, args);
return ret;
}
return descriptor;
}
// 镶嵌了红宝石的普通宝剑
// 普通宝剑类
export class Sword {
power: number;
@RedJewel //红宝石赋能
init(power: number): void {
this.power = power;
}
constructor() {
this.init(10)
}
showPower () {
console.log(`power is ${this.power}`)
}
}
let redJewelSword = new Sword();
redJewelSword.showPower(); // power is 20 =》 赋能后攻击力提升了10
WWH-HOW-nestJs如何赋能
// 举个例子
const ROLE_AMDIN = 'admin'; // 管理员角色
@Controller('api') // 使用@Controller赋能使该类拥有controller的特性,可以通过/api前缀访问对应的handler
@UseGuards(RolesGuard) // 使用@UseGuards赋能,使得该类的每一个handler均使用RolesGuard做路由守卫
export class ApiController {
constructor(private readonly apiService: ApiService) {}
@Get('findAll') // 使用@Get赋能, 通过get请求方式访问 /api/findAll 地址请求该handler
async findAll() {
return this.apiService.findAll(); // 自动判断是否使用jsonParse转为json数据,正常返回即可
}
@All() //使用@All赋能,是的所有请求方式都可以请求该handler; 因为path为空,所以路由挂在了根部位置,通过/api访问, 声明为All的话 可以使用method为 post、get、option、put、delete等方式进行请求获取数据
allMode(@Req() request, @Query() query, @Body() body) { // query为url上携带的查询数据eg. http://localhost:3000/api?a=1&b=2; body为post传过来的数据
console.log({query, body});
return {};
}
@Get('testInjectDto')
testInjectDto(@Query() apiDto: ApiDto) { // Api接口有name、url、params属性 相同名字的会被自动注入进而使用 eg.http://localhost:3000/api/testInjectDto?url=www.baidu.com&name=baidu&uuu=3
// apiDto.uuu 会报错
console.log(apiDto);
return apiDto;
}
@Roles(ROLE_AMDIN) //使用@Roles赋能使得访问该handler前会验证用户的权限 heander里面设置[{"key":"user","value":"{\"name\":\"a\",\"roles\":[\"admin\"]}","description":"","enabled":true}]
@Get('save')
@UsePipes(new ValidationPipe()) // 增加验证系统
async save(@Query() apiDto: ApiDto) {
this.apiService.create(apiDto);
return 'success';
}
}
WWH-WHAT-nestJs是什么
- nestJs是一个利用装饰器赋能的MVC后端框架
- 面向对象编程框架
- 基于express与socket.io
- 语法结构与ng2+类似,上手快,结构清晰
- 利用依赖注入机制,管理各个组件依赖
- 随时切换微服务与web服务,内置TCP通讯协议(微服务)、redis协议与HTTP通讯协议(web服务),支持其他自定义传输协议(易扩展性:通过实现自定义接口可以使用其他传输协议。eg.RabbitMq协议等)
理解几个概念
- 依赖注入:理解依赖注入之前,需要先明白什么是控制反转(IOC),简单的理解就是创建对象的控制权移交出去(由框架来创建),它包括依赖注入(Dependency Injection)和依赖查找(Dependency Lookup)两部分,依赖注入指框架通过对应的参数类型注入相应的对象,那么怎么知道这个对应的对象呢,其实涉及到依赖查找这一部分,简单的来说,框架会将需要注入的对象创建好放在一个容器中,当需要注入的时候在容器中查找有没有,有就直接注入,没有就创建一个放进容器里,所以此时大部分依赖注入的对象都是单例的(即同一个对象)。
WWH-WHAT-nestJs主要部件
- Module 模块-按业务逻辑划分
- Controller 控制器-处理请求和响应数据的部件(类比java的Action)
- Component 组件-处理实际业务逻辑的部件(类比java的Service)
- Middleware 中间件-路由处理Handler前的数据处理层
4.1 作用域-Module
4.2 举例-日志处理中间件、用户认证中间件等
4.3 访问域-由于nestJs的中间件和express的中间件一直,所以可以访问整个request、response的上下文
4.4 执行顺序-路由处理Handler前 - Pipe 管道-数据流处理(在中间件后路由处理前做数据处理)
5.1 作用域-Controller中的Class层、Method层、Argument层、全局作用域
5.2 举例-数据验证相关的验Pipe
5.3 访问域-数据值、对应的元数据
5.4 执行顺序-中间件层Middleware处理后、路由处理Handler前 - Guard 守卫-决定请求是否可以到达对应的路由处理器
6.1 作用域-Controller中的Class层、全局作用域
6.2 举例-角色守卫
6.3 访问域-能够知道当前的执行上下文(请求到达的是哪个Controller里面的哪个Handler)
6.4 执行顺序-中间件Middleware之后、拦截器Interceptor之前 -
Interceptor 拦截器
7.1 作用域-全局作用域
7.2 举例-日志拦截器、事务处理拦截器、异常处理拦截器等
7.3 访问域-能够知道当前的执行上下文(请求到达的是哪个Controller里面的哪个Handler)
7.4 执行顺序-守卫Guard之后、管道Pipe之前
各部件请求顺序图
未完待续。。。