Nest.js 入手以及企業化的思考

本人是一名 Node.js 實習生,在進入大搜車以後,有幸見識到 Akyuu.js 這個框架。可是這個框架是使用 Express + Callback 的方式,我不是很喜歡。在個人推薦以及社區的發展下,組長決定用 TS + Async/Await 來試一試。因而我也去了解了一下 TS 的後端框架有哪些,結果通過別人推薦,找到了 Nest.js 這個想法幾乎和我如出一轍的框架。node

框架簡介

由於我這個不是教程向,因此就不細講,能夠查看 Nest.js 官網。從個人感性角度來說,簡單說一下如下幾個特色:數據庫

  • 去中心化路由。全部的路由經過裝飾器與 Controller 綁定。簡單、明瞭,學習成本低。
  • TypeScript/Rx.js 加持。智能補全,代碼分析,靜態類型等等優勢。若是你只是我的用用的話,可能會以爲很全。可是放在企業當中使用,是很是大的優勢。
  • 依賴注入。從 Angular 那裏學習而來,可是進行了一些簡化,可是徹底夠用。好比說簡化掉了 deps。
  • 模塊思想。Node 社區的後端框架,其實都被 Express 導向到了中間件的模式。而 Nest.js 卻從 Angular 當中吸收到了模塊的思想。不一樣的 Service、Controller、Component 組成不一樣的模塊。模塊之間能夠相互依賴,也能夠獨立存在,這大大減小了測試和邏輯的複雜度。
  • 易於擴展。以往的框架,你能作的就是編寫業務邏輯,而其餘的你都很難去作到。因而傳統的後端框架不得不引入了一套插件機制來加強框架的擴展性。可是 Nest.js 將插件的功能直接內置到了框架當中。傳統的插件在這裏能夠認爲就是一個模塊,經過加載不一樣的模塊來添加不一樣的功能。
  • Express 基石。有人會說,不是如今 Koa 纔是更好的模型麼?洋蔥模型能夠解決更多複雜的問題。沒錯,我不反對這個言論。可是我想說的是,Express 仍是最簡單最通用的方式,由於他不賴 Generator/Promise,只須要你又一個 Node.js 運行環境,支持 Callback 就能夠了。(話說應該沒有不支持 Callback 的 Node.js 環境吧,哈哈哈)無論怎麼樣,Express 的覆蓋面仍是比 Koa 要廣很多。
  • 條條大路通羅馬。那麼有人就問了,那我要實現洋蔥模型怎麼辦呢?我想說,辦法老是會有的。而在 Nest.js 當中,經過 Interceptor ,能夠很好的實現洋蔥模型。也就是說你能夠經過 Interceptor 來記錄請求的耗時。
  • 同步代碼。這裏所說的同步代碼並非單單指的是 async/await。在不少支持 async/await 的框架中,若是你想返回值,若是是 Express ,你仍是須要調用 resp.send(await getValue()),而 koa 也是須要調用 ctx.body = await getValue()。可是在 Nest.js 中,只須要 return await getValue() 便可。實現真正的同步編寫業務邏輯代碼。
  • 邏輯分層。其實不少功能,都是能夠經過中間件來實現的。可是不一樣類型的功能有不一樣的需求,若是隻是經過中間件來實現,勢必會致使有一些重複的代碼。因而 Nest.js 裏面引入了 Pipe/Interceptor/Guard/ExceptionFilter 等邏輯層。不一樣的層裏面處理類似的事情,好比說 Pipe 處理的是輸入數據的轉換。而 Interceptor 來實現洋蔥模型。Guard 用於權限校驗等攔截任務。ExceptionFilter 用來處理錯誤數據。這種分層帶來的好處就是可讓代碼更加清晰,主須要思考這個層須要作的事情,而不須要站在中間件的層面去考慮這個事情。
  • Validation。自帶校驗,並且和 TS 結合的很是完美,使用起來很舒服,請看教程
  • 輸入參數的轉換。這個實際上是一個很方便的方面。有的時候你須要將輸入的參數轉換成一個類,這個時候你就能夠經過 Validation 進行轉換。你要是不想用自動轉換,能夠經過傳統的手動轉換的方式。
  • 測試功能完美。因爲採用了依賴注入,因此測試簡直簡單的不得了。並且官方也提供了一系列測試工具,也能很好的解決單元測試的問題。

Nest.js 企業化當中的問題

  • 目錄無約束。在企業當中,不對目錄進行約束會致使代碼愈來愈亂。從而下降了代碼可維護性。
  • 沒有配置管理功能。在框架開發中,配置每每是一個很重要的功能。好比說配置數據庫的鏈接,配置監聽的端口。
  • 沒有進程管理。雖然有提供 @nestjs/cli,可是這個提供的僅僅是一個項目的建立的能力。
  • 部分文檔講解不詳細,會提升入門的門檻。

不過總的來講,前面幾點也正是 Nest.js 靈活性的保證。可是咱們真正在開發當中,仍是須要一種合理的約束來保證開發的統一。後端

Nest.js 企業化的嘗試

那麼咱們這裏針對上面的幾個問題,嘗試採用一些方式來進行約束。bash

目錄結構

咱們對項目指定以下的規則:框架

  • 所有經過 TypeScript 書寫,而且所有位於 src 目錄下
  • 入口文件是 main.ts 若是沒有特殊狀況,不動這個文件
  • 配置放在 src/config 文件夾下
  • 全部的 Service/Controller/Logic/Component 等都掛載到 MainModule 下。
  • 其中 module 文件夾存放自定義的 Module,或者說但願獨立成模塊可是尚未徹底獨立出來的。其中目錄結構和這個項目目錄結構相似
  • boot 文件夾是項目啓動代碼的時候執行的,這部分在 Nest.js 當中沒有給出。我這裏打算添加這個功能,可是尚未想好具體的實現形式,因此待定。
  • interface/enum 等數據隨着對應的 service 導出。不另作說明。好比說 car.service.ts 除了能夠導出 CarService 類之外,還能夠導出 CarType enum。
  • dest 文件夾是編譯以後的文件,能夠直接輸入 node dest/main.js 運行。
  • 命名規則
    • 全部的文件除了 main.ts 和類文件之外,都要添加類型後綴,好比說 user.model.ts car.controller.ts google.logic.ts。可是好比說只是一個 Car 類,那麼能夠直接命名成 car.ts
    • 不容許經過 export default 導出數據。一方面是爲了方便導入的時候保證命名的統一,另外一方面能夠隨時導出 interface/enum 等內容。
    • 全部的測試文件後綴名都以 .spec.ts.test.ts 結尾。
|-- dest
    |--- ...
|-- src
    |-- config
    |-- controller
    |-- model
    |-- service
    |-- logic
    |-- component
    |-- boot
    |-- module
        |-- module-name
            |-- config
            |-- index.ts
            |-- module-name.module.ts
    |-- main.ts
    |-- main.module.ts
複製代碼

配置管理

我目前初步的想法是經過提供一個 ConfigModule 暴露出一個 ConfigService 來提供配置的獲取和查看。koa

在某些狀況下,可能須要多級配置,模塊級別的配置,應用級別的配置。那麼 ConfigService 能夠在獲取配置的時候自動合併這些規則。async

進程管理

如今已是 18 年了,不用 Docker 你真的對得起本身麼?很明顯是對不起的。因此進程管理這一塊,咱們就交給 Docker 來處理。包括啓動、中止、重啓、日誌等,都交給 Docker。工具

因而啓動命令就能夠簡化成 node dest/main.js 便可。單元測試

那麼你可能會想到,若是一個 Docker 環境給你分配了兩個 u,那豈不是會浪費一個 u。理論上是的,那麼你就能夠經過 pm2 啊啥的本身去管理吧,哈哈哈,無論。學習

Iron.js

說了這麼多,把上面的內容都沉澱下來,我得要給他取個名字,因而我就取成了 Iron。爲啥叫 Iron 呢?由於 Iron Man。那爲啥由於 Iron Man 呢?由於他製做的盔甲能夠自由拆分,自動拼合。很是適合咱們這個項目的形態。

不過這個項目何時能沉澱下來,看我心情了。不過定個時間線吧,就在 4 月底,爭取搞定。

由於這裏面最大的問題就是配置的問題,須要深刻依賴注入,因此會麻煩一些。可是其餘的方面更多的只是一種約束吧。

這就是我用 Nest.js 一週以來的心得。暫時就想到這麼多,更多的內容等我後面再分析吧。

寫完睡覺,答應女票了,啦啦啦~

相關文章
相關標籤/搜索