裝飾器賦能-nestJs概念初識

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

  1. nestJs是一個利用裝飾器賦能的MVC后端框架
  2. 面向對象編程框架
  3. 基于express與socket.io
  4. 語法結構與ng2+類似,上手快,結構清晰
  5. 利用依賴注入機制,管理各個組件依賴
  6. 隨時切換微服務與web服務,內置TCP通訊協議(微服務)、redis協議與HTTP通訊協議(web服務),支持其他自定義傳輸協議(易擴展性:通過實現自定義接口可以使用其他傳輸協議。eg.RabbitMq協議等)
理解幾個概念
  1. 依賴注入:理解依賴注入之前,需要先明白什么是控制反轉(IOC),簡單的理解就是創建對象的控制權移交出去(由框架來創建),它包括依賴注入(Dependency Injection)和依賴查找(Dependency Lookup)兩部分,依賴注入指框架通過對應的參數類型注入相應的對象,那么怎么知道這個對應的對象呢,其實涉及到依賴查找這一部分,簡單的來說,框架會將需要注入的對象創建好放在一個容器中,當需要注入的時候在容器中查找有沒有,有就直接注入,沒有就創建一個放進容器里,所以此時大部分依賴注入的對象都是單例的(即同一個對象)。

WWH-WHAT-nestJs主要部件

  1. Module 模塊-按業務邏輯劃分
  2. Controller 控制器-處理請求和響應數據的部件(類比java的Action)
  3. Component 組件-處理實際業務邏輯的部件(類比java的Service)
  4. Middleware 中間件-路由處理Handler前的數據處理層
    4.1 作用域-Module
    4.2 舉例-日志處理中間件、用戶認證中間件等
    4.3 訪問域-由于nestJs的中間件和express的中間件一直,所以可以訪問整個request、response的上下文
    4.4 執行順序-路由處理Handler前
  5. Pipe 管道-數據流處理(在中間件后路由處理前做數據處理)
    5.1 作用域-Controller中的Class層、Method層、Argument層、全局作用域
    5.2 舉例-數據驗證相關的驗Pipe
    5.3 訪問域-數據值、對應的元數據
    5.4 執行順序-中間件層Middleware處理后、路由處理Handler前
  6. Guard 守衛-決定請求是否可以到達對應的路由處理器
    6.1 作用域-Controller中的Class層、全局作用域
    6.2 舉例-角色守衛
    6.3 訪問域-能夠知道當前的執行上下文(請求到達的是哪個Controller里面的哪個Handler)
    6.4 執行順序-中間件Middleware之后、攔截器Interceptor之前
  7. Interceptor 攔截器
    7.1 作用域-全局作用域
    7.2 舉例-日志攔截器、事務處理攔截器、異常處理攔截器等
    7.3 訪問域-能夠知道當前的執行上下文(請求到達的是哪個Controller里面的哪個Handler)
    7.4 執行順序-守衛Guard之后、管道Pipe之前


    各部件請求順序圖

    未完待續。。。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,837評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,829評論 25 708
  • 如果讓我自己選擇的話,《飛越來生緣》這部電影估計我不會看完,但它是必須完成的限時任務,所以我在中間插入觀看了一部兩...
    銥漩娜閱讀 3,827評論 0 2
  • 如果在童年的時候你就明確的知道自己是怎么死的,你會怎么過這一生? 這個問題很有趣,大學期間,基本上把豆瓣top25...
    楊pure閱讀 296評論 0 1
  • 02 昨天我在家里寫稿。 白飯突然在大廳高聲大喊:“沒網啦沒網啦!” 我爸正好從外面工作回來,聽見了白飯的聲音,一...
    講故事的余姑娘閱讀 131評論 1 3