<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          NestJS 探索與實踐

          共 4988字,需瀏覽 10分鐘

           ·

          2024-04-11 12:13

          3e7049dcebb262092dce173cc58e5645.webp

          前段時間,我司前端基建團隊上線了重定向管理系統(tǒng)——它提供二維碼、短鏈接的創(chuàng)建和維護服務。

          這是由前端團隊全棧開發(fā)的項目:前端使用 React,后端使用 Nestjs 開發(fā)。我們將開發(fā)過程中得到的一些實踐經(jīng)驗和思考,借著這個機會想和大家共同探討一下。也希望通過這次分享,讓大家對 NestJS 有一個初步的了解。

          主題

          這次分享主要包含4個內容

          • 什么是 nestJS?

          • 應用場景和能力,能解決什么問題?

          • 為什么選擇它,有什么優(yōu)勢?

          • 如何上手?

          What

          da7dd9b4d8530f59565271bea521ab9d.webp 我們先回答第一個問題:什么是 nestJS。圖中是官網(wǎng)的一段定義,大意是:

          Nest 是一個用于構高效,可擴展的 Node.js 服務端應用程序的框架…… 它使用漸進式 JavaScript,內置并完全支持 TypeScript

          從定義中,我們找出幾個關鍵字來看看:

          • 基于 Node:對前端友好

          • 服務端應用框架:主要用于服務端接口開發(fā)

          • 高效,可擴展:體現(xiàn)在 Nest 各個功能模塊之間的架構是解耦的、容易進行組合的

          • 漸進式:不需要一開始掌握它的全部功能特性,后續(xù)可根據(jù)業(yè)務需要逐步增加功能。

          • Nest 由 TS 開發(fā),完全支持 TS

          簡單來說,Nest 是一個具有諸多特性的 Node 服務端框架。

          When

          第二個問題:有哪些應用場景和能力?能解決什么問題?

          1. 首先是最基礎的,做服務端開發(fā);

          2. 其次,對服務端功能的擴展,比如:安全、鑒權、隊列、日志等

          3. 技術架構級支持:微服務,序列化等等

          以上這些場景,官方都提供成熟的解決方案,對技術選型也是一種可靠的保障。

          Why

          說完 Nest 的應用場景,我們再來談談:為什么選擇 Nest?我們簡單回顧一下 Node Web 框架的發(fā)展歷程,我這里將它們分為 起步和規(guī)模化 兩個階段:

          82fafabb1e45a3571860b9f1e7a7a8de.webp

          起步階段 從 09 年 Node.js誕生開始,緊接著出現(xiàn) Express,Koa。它們主打輕量、極簡的框架

          • 它們開發(fā)風格自由開放,導致的結果是:大家都有自己的一套開發(fā)方式(不同的分層,項目結構,文件命名)。

          • 框架功能過于專一甚至簡單,團隊項目很少直接使用它們開發(fā);它們的特點好像 web 中的 JQuery,依然強大,但已經(jīng)不能滿足復雜的開發(fā)需求

          在這樣的背景下,誕生了 Egg 和 Nest——主打企業(yè)級應用和團隊協(xié)作,開箱即用

          Nest 與 Egg 對比

          Express 和 Koa 功能比較基礎,Nest 與 Egg 是我們主要考慮的兩種方案,我們通過以下幾個方面來進行比較:

          1c209db7eb0f7e1d7662525330421189.webp

          • 社區(qū)生態(tài):Nest 社區(qū)非常繁榮,由官方提供解決方案;Egg 擁有插件市集,但插件質量參差不齊

          • 關注度,Nest 在 GitHub 上有 4.2 萬 star,Egg 是 1.8 萬(截止2022年1月);

          • 項目更新頻率:Nest 高一些,github issue 反饋及時,使用體驗更好

          • 架構設計:代碼組織方式更合理——項目結構按照功能模塊劃分;裝飾器語法更加優(yōu)雅;基于依賴注入實現(xiàn)代碼低耦合;Egg 提倡約定大于配置,缺乏一定的靈活性

          • Nest 原生支持 TS

          • 上手難度:Nest 概念較多,難度稍高一點

          • 維護成本,Nest 有一套標準化的開發(fā)流程,長期來看,利于保持項目的統(tǒng)一性

          綜合以上幾個方面,我們認為:Nest 設計更加合理,也更適合我們團隊

          去年 12月, 阿里的 D2 大會上,也推出新的 Node Web 框架:MidWay。整體設計和 Nest 比較類似:支持裝飾器,基于 DI 設計,支持 TS —— Egg.js 似乎完成了他的歷史使命,將接力棒交到了 Midway 的手中

          How

          接下來我們從代碼層面,介紹如何上手 Nest

          腳手架

          030a6307fb11b2b5718a57e0bbb7eeb1.webp

          • Nest 官方提供了腳手架,可通過 npm 全局安裝,使用方法與 Vue client 大同小異,開發(fā)體驗是比較不錯的

          • 使用 Nest CLI 建立新項目非常簡單,通過 nest new xxx 一鍵創(chuàng)建,會生成樣板代碼、安裝依賴

          • 使用命令 npm start:dev 啟動應用程序,監(jiān)聽入站 HTTP 請求。

          目錄結構

          初始化的項目包含一些樣板文件,主要看一下 src 目錄,里面包含了幾個核心文件

          982649255476696cd9d4d967af10cef3.webp

          main.ts

          main.ts 是程序的入口文件,它包含一個異步函數(shù):負責創(chuàng)建 app 實例,啟動、監(jiān)聽服務器。內部引入了 app.module —— 模塊文件,這是 Nest 一個核心概念

          基礎概念

          module

          • 中文名叫模塊,在 Nest 中是可運行功能的最小單元。

          8afca0edfb78ae8b017462a9f7b46c3d.webp

          • 舉個例子,我們的應用中有 用戶管理,訂單管理 等多個功能,每個功能都可獨立成一個模塊,下面這幅圖,虛線表示服務端應用,其中用戶管理功能是 UserModule,訂單管理是 OrderModule,應用則是由許多的模塊 moudule 組成……在他們前面還有一個 AppModule,是整個應用根模塊

          d2331c462f5f502b4a780a7b1ef3a8c7.webp

          • 整個模塊的結構類似前端 SPA 應用:前端應用 app 掛載到 root 根節(jié)點上,pages 目錄下的文件映射為不同的頁面組件

          • 為了創(chuàng)建一個基本的模塊,我們將使用  和 裝飾器

          裝飾器

          bd77f52a23a4e6e1c70b7c35431039dd.webp

          • 裝飾器是一種特殊的語法,它用來修改或增強類、函數(shù)、對象等,寫法是 @expression, 在 TS 中率先支持這種語法

          • expression 表達式求值后必須為一個函數(shù),它會在運行時被調用;被裝飾的主體做為參數(shù)傳入。

          • 代碼中在 AppModule 這個類前面,添加了一個 @Module() 裝飾器,作用是返回一個模塊類,并提供模塊的元數(shù)據(jù)(上下文及依賴)。

          app.module.ts 中引入了 Controller 和 Service ,我順著代碼的依賴關系,來介紹一下 Controller

          controller

          f40f78cfb68c5ad5e168797eae81b47b.webp

          • 控制器,負責處理傳入的請求和返回的響應

          • 它像一個處理器(dispatcher),接收 HTTP 請求,然后通過 路由分發(fā) 機制,調用命中的方法

          • @Get 這個請求類型裝飾器,可以接受一個路由地址。如果路由命中,則會調用 getHello 方法;這里為空,會匹配根路徑

          • 控制器重要負責處理 HTTP 請求,而將更復雜的任務委托給提供者,即 Service(providers), Service 是什么?

          Service

          44126f9034740daad2c62db40f7a345c.webp

          • 在 Nest 中,服務 是一種常見的 提供者(Provider) ,它負責一些基礎、公用的方法,比如處理業(yè)務邏輯,與數(shù)據(jù)庫交互……提供者通過依賴注入的方式,被注入到控制器(Controller)中,這些方法由 Controller 調用。

          剛剛介紹了Nest 中最核心的三個概念

          • 模塊是 Nest 中的最小單元,許許多多的單元組成了應用;也可以看作一個容器,如下圖,每個模塊中包含了控制器和提供者

          0b90abc0829861ae84087fdf47cc0441.webp

          • 控制器處理 HTTP 請求,分發(fā)路由;調用提供者的方法;

          • 提供者中定義了基礎/公共的邏輯

          需要注意的是:

          • 在開發(fā)中為了避免把邏輯分散在各個文件中,要注意區(qū)分控制器和提供者邊界,

          即:

          • 在 Controller 中主要處理請求、分發(fā)路由;注意,一個控制器中可以調用多個提供者;

          • 在提供者中處理基礎業(yè)務邏輯

          如下圖代碼…這樣進行功能分層,能夠保障代碼的清晰和統(tǒng)一

          ed59cab8fb4139e358fa69c8d48f0576.webp

          除此之外,Nest 還有中間件(在路由程序前后執(zhí)行),異常過濾器(處理程序拋出的異常錯誤),守衛(wèi)(權限校驗)……等概念,用于開發(fā)一些常見的功能。但我沒有把它們歸類到 Nest 核心概念中,大家有興趣下來可以再了解。

          依賴注入

          前面經(jīng)常講到 Nest 是可擴展,低耦合的,那么它是怎么實現(xiàn)的呢?答案是:依賴注入

          依賴注入(Dependecy Injection)是實現(xiàn)低耦合的一種方式(也可以叫設計模式),它將對象創(chuàng)建和對象消耗分開。所需的依賴關系不是在內部創(chuàng)建,而是通過外部透明地傳遞

          這里有一段代碼,包含兩個類:第一個是 引擎 Engine,第二個是 汽車 Car

          b4433967fa5b05e1a81436726da253cf.webp

          • Engine 有一個 cylinders 屬性,表示引擎類型,我先給他一個固定屬性為內燃機引擎

          • Car 構造器中通過 new 實例化了一個引擎,在 drive 方法中使用了引擎的類屬性,返回字符串:這是一個內燃機引擎汽車

          • 有一天,我打算改動 Engine,不再設置固定類型,而是通過構造器動態(tài)傳入;那么,Car 也需要改動構造函數(shù)中的代碼。這樣一來就不符合低耦合的標準。

          9a1f4d5a61d1744fc69ba386cf043201.webp 那我們使用依賴注入的方式,該怎么處理?

          162f51c1030987a619aa8266dcd8610f.webp

          • 在汽車中,通過構造函數(shù)直接傳遞 Engine 對象,而不是在內部創(chuàng)建

          • 在外部 main 方法中,實例化 Car 時,也會實例化 Engine 對象,并把 Engine 傳入到 Car 中;這個過程叫做注入;注意,這里是把 Engine 傳入到 Car 中;

          • 這樣修改后,無論 Engine 的邏輯怎樣改變,都不會影響到 Car 的代碼

          我們再回頭看一下,Nest 中是怎么應用依賴注入的?

          • 回到 Module 文件,@Module 裝飾器中會聲明 controllers 和 providers@Module 裝飾器實際是替代了 main 函數(shù)。會實例化 Controller 和 Provider,并將 Provider 注入到 Controller 中

          18998b5554045b515c3b9d6a96fdfa7f.webp

          • 于是在 Controller 中可以通過 this 調用 service。

          470b39915c8346877c3abc0d272ef03c.webp

          Nest 中是將 provider 注入到 controller,因此 Provider 的裝飾器名字叫做 Injectable

          這就是在 Nest 從框架層面,通過依賴注入實現(xiàn)模塊的低耦合,從而提高了代碼的可擴展性。

          Summary

          通過上面對 Nest 的講解,簡單總結一下:

          第一:我們主要從四個方面來介紹了 Nest:What,When,Why,How

          第二:Nest 存在一些缺點:它的概念較多;設計模式與平常不一樣;國內開發(fā)者目前比較少;

          總體評價 Nest.js,我覺得它是一個「優(yōu)雅的,標準化,可擴展的」 Node 框架。在使用過程中除了知道這玩意怎么用,也能慢慢學習到后端開發(fā)模式,Nest 在的設計上的優(yōu)點也是值得我們學習和探索的。


          作者:samwangdd

          鏈接:https://juejin.cn/post/7054931414478749710

          來源:稀土掘金

          瀏覽 59
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  丁香五月婷婷网 | 午夜三级免费福利影院 | 丁香欧美 | 91啦国产| 在线看a黄色片……` |