貓眼鄭志昊提出連接、賦能、破界是互聯網下半場的創新法則。賦能這個詞個人理解的意思是賦予更多的能力,創造更多的價值。例如技術賦能、數據賦能、運營賦能等等。
此次我們介紹的框架是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之前
各部件請求順序圖
未完待續。。。