中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Node后端框架Nest.js的AOP 架構有什么用

發布時間:2022-03-22 09:38:26 來源:億速云 閱讀:238 作者:小新 欄目:web開發

這篇文章主要介紹Node后端框架Nest.js的AOP 架構有什么用,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!

Nest.js 是一個 Nodejs 的后端框架,它對 express 等 http 平臺做了一層封裝,解決了架構問題。它提供了 express 沒有的 MVC、IOC、AOP 等架構特性,使得代碼更容易維護、擴展。

這里的 MVC、IOC、AOP 都是啥意思呢?我們分別看一下:

MVC、IOC

MVC 是 Model View Controller 的簡寫。MVC 架構下,請求會先發送給 Controller,由它調度 Model 層的 Service 來完成業務邏輯,然后返回對應的 View。

Node后端框架Nest.js的AOP 架構有什么用

Nest.js 提供了 @Controller 裝飾器用來聲明 Controller:

Node后端框架Nest.js的AOP 架構有什么用

而 Service 會用 @Injectable 裝飾器來聲明:

Node后端框架Nest.js的AOP 架構有什么用

通過 @Controller、@Injectable 裝飾器聲明的 class 會被 Nest.js 掃描,創建對應的對象并加到一個容器里,這些所有的對象會根據構造器里聲明的依賴自動注入,也就是 DI(dependency inject),這種思想叫做 IOC(Inverse Of Control)。

IOC 架構的好處是不需要手動創建對象和根據依賴關系傳入不同對象的構造器中,一切都是自動掃描并創建、注入的。

此外,Nest.js 還提供了 AOP (Aspect Oriented Programming)的能力,也就是面向切面編程的能力:

AOP

AOP 是什么意思呢?什么是面向切面編程呢?

一個請求過來,可能會經過 Controller(控制器)、Service(服務)、Repository(數據庫訪問) 的邏輯:

Node后端框架Nest.js的AOP 架構有什么用

如果想在這個調用鏈路里加入一些通用邏輯該怎么加呢?比如日志記錄、權限控制、異常處理等。

容易想到的是直接改造 Controller 層代碼,加入這段邏輯。這樣可以,但是不優雅,因為這些通用的邏輯侵入到了業務邏輯里面。能不能透明的給這些業務邏輯加上日志、權限等處理呢?

那是不是可以在調用 Controller 之前和之后加入一個執行通用邏輯的階段呢?

比如這樣:

Node后端框架Nest.js的AOP 架構有什么用

這樣的橫向擴展點就叫做切面,這種透明的加入一些切面邏輯的編程方式就叫做 AOP (面向切面編程)。

AOP 的好處是可以把一些通用邏輯分離到切面中,保持業務邏輯的存粹性,這樣切面邏輯可以復用,還可以動態的增刪

其實 Express 的中間件的洋蔥模型也是一種 AOP 的實現,因為你可以透明的在外面包一層,加入一些邏輯,內層感知不到。

而 Nest.js 實現 AOP 的方式更多,一共有五種,包括 Middleware、Guard、Pipe、Inteceptor、ExceptionFilter:、

中間件 Middleware

Nest.js 基于 Express 自然也可以使用中間件,但是做了進一步的細分,分為了全局中間件和路由中間件:

全局中間件就是 Express 的那種中間件,在請求之前和之后加入一些處理邏輯,每個請求都會走到這里:

Node后端框架Nest.js的AOP 架構有什么用

路由中間件則是針對某個路由來說的,范圍更小一些:

Node后端框架Nest.js的AOP 架構有什么用

這個是直接繼承了 Express 的概念,比較容易理解。

再來看一些 Nest.js 擴展的概念,比如 Guard:

Guard

Guard 是路由守衛的意思,可以用于在調用某個 Controller 之前判斷權限,返回 true 或者 flase 來決定是否放行:

Node后端框架Nest.js的AOP 架構有什么用

創建 Guard 的方式是這樣的:

Node后端框架Nest.js的AOP 架構有什么用

Guard 要實現 CanActivate 接口,實現 canActive 方法,可以從 context 拿到請求的信息,然后做一些權限驗證等處理之后返回 true 或者 false。

通過 @Injectable 裝飾器加到 IOC 容器中,然后就可以在某個 Controller 啟用了:

Node后端框架Nest.js的AOP 架構有什么用

Controller 本身不需要做啥修改,卻透明的加上了權限判斷的邏輯,這就是 AOP 架構的好處。

而且,就像 Middleware 支持全局級別和路由級別一樣,Guard 也可以全局啟用:

Node后端框架Nest.js的AOP 架構有什么用

Guard 可以抽離路由的訪問控制邏輯,但是不能對請求、響應做修改,這種邏輯可以使用 Interceptor:

Interceptor

Interceptor 是攔截器的意思,可以在目標 Controller 方法前后加入一些邏輯:

Node后端框架Nest.js的AOP 架構有什么用

創建 Inteceptor 的方式是這樣的:

Node后端框架Nest.js的AOP 架構有什么用

Interceptor 要實現 NestInterceptor 接口,實現 intercept 方法,調用 next.handle() 就會調用目標 Controller,可以在之前和之后加入一些處理邏輯。

Controller 之前之后的處理邏輯可能是異步的。Nest.js 里通過 rxjs 來組織它們,所以可以使用 rxjs 的各種 operator。

Interceptor 支持每個路由單獨啟用,只作用于某個 controller,也同樣支持全局啟用,作用于全部 controller:

Node后端框架Nest.js的AOP 架構有什么用

Node后端框架Nest.js的AOP 架構有什么用

除了路由的權限控制、目標 Controller 之前之后的處理這些都是通用邏輯外,對參數的處理也是一個通用的邏輯,所以 Nest.js 也抽出了對應的切面,也就是 Pipe:

Pipe

Pipe 是管道的意思,用來對參數做一些驗證和轉換:

Node后端框架Nest.js的AOP 架構有什么用

創建 Pipe 的方式是這樣的:

Node后端框架Nest.js的AOP 架構有什么用

Pipe 要實現 PipeTransform 接口,實現 transform 方法,里面可以對傳入的參數值 value 做參數驗證,比如格式、類型是否正確,不正確就拋出異常。也可以做轉換,返回轉換后的值。

內置的有 8 個 Pipe,從名字就能看出它們的意思:

  • ValidationPipe

  • ParseIntPipe

  • ParseBoolPipe

  • ParseArrayPipe

  • ParseUUIDPipe

  • DefaultValuePipe

  • ParseEnumPipe

  • ParseFloatPipe

同樣,Pipe 可以只對某個路由生效,也可以對每個路由都生效:

Node后端框架Nest.js的AOP 架構有什么用

Node后端框架Nest.js的AOP 架構有什么用

不管是 Pipe、Guard、Interceptor 還是最終調用的 Controller,過程中都可以拋出一些異常,如何對某種異常做出某種響應呢?

這種異常到響應的映射也是一種通用邏輯,Nest.js 提供了 ExceptionFilter 來支持:

ExceptionFilter

ExceptionFilter 可以對拋出的異常做處理,返回對應的響應:

Node后端框架Nest.js的AOP 架構有什么用

創建 ExceptionFilter的形式是這樣的:

Node后端框架Nest.js的AOP 架構有什么用

首先要實現 ExceptionFilter 接口,實現 catch 方法,就可以攔截異常了,但是要攔截什么異常還需要用 @Catch 裝飾器來聲明,攔截了異常之后,可以異常對應的響應,給用戶更友好的提示。

當然,也不是所有的異常都會處理,只有繼承 HttpException 的異常才會被 ExceptionFilter 處理,Nest.js 內置了很多 HttpException 的子類:

  • BadRequestException

  • UnauthorizedException

  • NotFoundException

  • ForbiddenException

  • NotAcceptableException

  • RequestTimeoutException

  • ConflictException

  • GoneException

  • PayloadTooLargeException

  • UnsupportedMediaTypeException

  • UnprocessableException

  • InternalServerErrorException

  • NotImplementedException

  • BadGatewayException

  • ServiceUnavailableException

  • GatewayTimeoutException

當然,也可以自己擴展:

Node后端框架Nest.js的AOP 架構有什么用

Nest.js 通過這樣的方式實現了異常到響應的對應關系,代碼里只要拋出不同的 HttpException,就會返回對應的響應,很方便。

同樣,ExceptionFilter 也可以選擇全局生效或者某個路由生效:

某個路由:

Node后端框架Nest.js的AOP 架構有什么用

全局:

Node后端框架Nest.js的AOP 架構有什么用

我們了解了 Nest.js 提供的 AOP 的機制,但它們的順序關系是怎樣的呢?

幾種 AOP 機制的順序

Middleware、Guard、Pipe、Interceptor、ExceptionFilter 都可以透明的添加某種處理邏輯到某個路由或者全部路由,這就是 AOP 的好處。

但是它們之間的順序關系是什么呢?

調用關系這個得看源碼了。

對應的源碼是這樣的:

Node后端框架Nest.js的AOP 架構有什么用

很明顯,進入這個路由的時候,會先調用 Guard,判斷是否有權限等,如果沒有權限,這里就拋異常了:

Node后端框架Nest.js的AOP 架構有什么用

拋出的 HttpException 會被 ExceptionFilter 處理。

如果有權限,就會調用到攔截器,攔截器組織了一個鏈條,一個個的調用,最后會調用的 controller 的方法:

Node后端框架Nest.js的AOP 架構有什么用

調用 controller 方法之前,會使用 pipe 對參數做處理:

Node后端框架Nest.js的AOP 架構有什么用

會對每個參數做轉換:

Node后端框架Nest.js的AOP 架構有什么用

ExceptionFilter 的調用時機很容易想到,就是在響應之前對異常做一次處理。

而 Middleware 是 express 中的概念,Nest.js 只是繼承了下,那個是在最外層被調用。

這就是這幾種 AOP 機制的調用順序。把這些理清楚,就算是對 Nest.js 有很好的掌握了。

總結

Nest.js 基于 express 這種 http 平臺做了一層封裝,應用了 MVC、IOC、AOP 等架構思想。

MVC 就是 Model、View Controller 的劃分,請求先經過 Controller,然后調用 Model 層的 Service、Repository 完成業務邏輯,最后返回對應的 View。

IOC 是指 Nest.js 會自動掃描帶有 @Controller、@Injectable 裝飾器的類,創建它們的對象,并根據依賴關系自動注入它依賴的對象,免去了手動創建和組裝對象的麻煩。

AOP 則是把通用邏輯抽離出來,通過切面的方式添加到某個地方,可以復用和動態增刪切面邏輯。

Nest.js 的 Middleware、Guard、Interceptor、Pipe、ExceptionFileter 都是 AOP 思想的實現,只不過是不同位置的切面,它們都可以靈活的作用在某個路由或者全部路由,這就是 AOP 的優勢。

我們通過源碼來看了它們的調用順序,Middleware 是 Express 的概念,在最外層,到了某個路由之后,會先調用 Guard,Guard 用于判斷路由有沒有權限訪問,然后會調用 Interceptor,對 Contoller 前后擴展一些邏輯,在到達目標 Controller 之前,還會調用 Pipe 來對參數做驗證和轉換。所有的 HttpException 的異常都會被 ExceptionFilter 處理,返回不同的響應。

Nest.js 就是通過這種 AOP 的架構方式,實現了松耦合、易于維護和擴展的架構。

AOP 架構的好處,你感受到了么?

以上是“Node后端框架Nest.js的AOP 架構有什么用”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

永兴县| 施甸县| 积石山| 临清市| 察雅县| 康马县| 衡阳市| 观塘区| 遵义市| 本溪市| 弥勒县| 调兵山市| 陆丰市| 陵川县| 呼玛县| 宜川县| 尚义县| 介休市| 通化市| 包头市| 滦平县| 定襄县| 万全县| 神木县| 西昌市| 万载县| 新乡县| 繁昌县| 财经| 黄平县| 新干县| 惠安县| 深泽县| 体育| 湘潭市| 宁都县| 新巴尔虎右旗| 陵水| 翼城县| 渝北区| 密山市|