【譯】如何用 TypeScript 玩轉後端?

希裡花斯發表於2017-12-17

如何用 TypeScript 玩轉後端?

我將從一個開發者的角度介紹幾個優秀的庫。它們可以滿足你後端應用的絕大部分特性。裝飾器和後設資料的能力在這些庫中得到的充分的應用,使其非常強大並且簡單易用。

我希望這篇文章可以幫到像我這樣,喜歡 TypeScript 而且想用它編寫後端程式碼的人,讓他們像我一樣發現這些庫之後樂在其中。

TL;DR —— 堆疊使你的後端應用像許多使用其他語言的企業靜態解決方案一樣強大:

  • 使用裝飾器,引數,body 注入的路由和控制器的庫

  • 依賴注入和使用裝飾器的 services 的庫

  • 使用裝飾器的 ORM 就像 Doctrine/Hibernate 那樣方便操作實體

  • 給那些還不熟悉使用 TypeScript 寫後端的朋友的小建議

Routing-controllers:控制器,行為,請求等

pleerock/routing-controllers routing-controllers —— 建立結構化,宣告性和組織良好的基於類的控制器

儘管這個庫是作為 Express/Koa 的 TypeScript helper 編寫的,它也會對你編寫控制器有所幫助,就像你在 Java/PHP/C# 的企業級框架裡用到的那樣。

下面是一個控制器的小例子:

import {JsonController, Param, Body, Get, Post, Put, Delete} from "routing-controllers";

@JsonController()
export class UserController {

    @Get("/users")
    getAll() {
       return userRepository.findAll();
    }

    @Get("/users/:id")
    getOne(@Param("id") id: number) {
       return userRepository.findById(id);
    }

    @Post("/users")
    post(@Body() user: User) {
       return userRepository.insert(user);
    }

}
複製程式碼

這對一些人來說就像是擺脫了噩夢:不再有帶路由的元件,充滿巢狀的中介軟體以及具有注入,驗證和請求引數的中介軟體的實現(是的,你甚至可以定義引數型別和是否必傳!如 @Body({ required: true, validate: true }) 這種寫法將能很好地工作,如果缺少引數或者不正確的請求就會丟擲異常)

裝飾器有很多有用的特性,如基礎控制器的 @Controller,可在 actions 中定義內容的型別以及使用 @JsonController 服務和接收 JSON。

我正在 Express 中使用它,既然我們有了 async/await (即使 TS Node.js 開發已經過了好幾個月我還是忍不住讚美)我們似乎不再需要 Koa 了(現在 routing-controllers 可以更好的支援 Express )。而且 Express 有更大的型別集 @types。

下面是我專案中使用 routing-controllers 和其他 @pleerock 庫(VSCode, 如果有興趣的話,引用來自 TypeLens 外掛)的例子:

【譯】如何用 TypeScript 玩轉後端?

如你所見,routing-controllers 甚至提供了 undefined 返回碼(也有 empty 和 null 的裝飾器)以及許多其他特性。關於 this.playerService —— 這是另一個迷人的庫,稍後我將介紹它。

總體來看,庫有強大的文件,它可以幫助你理解和構建適用於操作甚至整個控制器的自定義中介軟體的應用程式(這對我來說是個絕妙的時刻)。連結地址如你所見就在那,非常方便。

當然,你也可以使用很多 Express/Koa 中介軟體把你的應用抽離出來,以及檢視配置(庫也有針對檢視的裝飾器),認證(可以通過中介軟體應用到整個控制層),錯誤處理等方面的配置。

通常我把他們存放在 /controllers 資料夾。

TypeDI:依賴注入,services

github.com/pleerock/ty…

這個庫幫我定好了專案結構,方便編碼並且不用去想「好吧 service 存在哪裡,這個是 service?唔或許是另一個,但是,它怎麼依賴另一個 service?怎麼引用其他 service 唔。」

回到我的 PlayerService,下面這部分你可以看到它依賴了什麼(其他 services):

【譯】如何用 TypeScript 玩轉後端?

@Inject 對我來說是在處理 services 和邏輯完整的後端應用方面最好用的裝飾器。

(如果你想了解 @OrmEntityManager —— 另一個來自 @pleerock 的庫,稍後我將講解)

是的,你可以有很多 services 依賴其他的 services。並且如果你有 service 迴圈依賴,你可以通過明確地定義型別來解決這個問題(庫的文件涵蓋了大部分的問題和情景)

對那些不熟悉 services,service 容器,services 依賴注入等的朋友。簡要說明:

你有某種功能,想把它存在類中,然後你想要類的例項並且想讓這個類依賴另一個,另一個等。service 容器的依賴注入可以為你保駕護航。你可以從容器中獲取 services 並且它會自己處理 services 的所有依賴,給你帶有其他例項的工作例項自動注入。

我關於這個庫的描述並不涵蓋它的所有潛能(你可以自己檢視它的文件——有更多的特性可以使用):你可以在定義 services 時給它命名,還可以定義構造器注入等。

通常我把我的 services 存放在 /services 資料夾。

TypeORM:使用 ORM 定義關係型實體,不同列型別和不同資料儲存方案非常方便(關係型,非關係型)

typeorm/typeorm_typeorm —— 可在 TypeScript and JavaScript (ES7, ES6, ES5)環境中使用的 Data-Mapper ORM。支援 MySQL, PostgreSQL, MariaDB, SQLite

這給我的感覺就是,用 TypeScript 寫 Node.js 最終有能力跟其他語言和 ORMS 競爭。

強大的 ORM 可以讓你很方便地用一種可理解的方式編寫實體。我不是其他許多類似這種 Node.js ORMS 的粉絲:

module.exports = { id: SomeORM.Integer, name: SomeOrm.String({ …})}
複製程式碼

我總是想讓實體寫成類。被賦予型別的屬性的類,會被帶有簡單裝飾器的 ORM 發現。甚至是沒有型別的。

TypeORM 給你這種能力。我專案中的另一個例子:

【譯】如何用 TypeScript 玩轉後端?

如你所見,我甚至沒在裝飾器中寫屬性的型別(你可以這樣做,不要擔心,明確地定義型別,預設的,可空的等)!TypeORM 為我做了所有這些工作,瞭解什麼型別(感謝 TypeScript 反射:後設資料擴充套件功能)以及把它應用在我的資料庫。

它非常強大,你將擁有所有你在其他 ORMs 中擁有/看到的東西,比如(Doctrine, Hibernate)。

當使用 routing-controllers 和 TypeDI,它會為你注入實體管理器(就像你在我的 PlayerService 截圖中看到的一樣)提供非常有用的裝飾器或者連線你的控制器和 services(這非常方便)。

這個 ORM 有一個涵蓋了大量功能的官方文件,你可以看看並且從中瞭解所有你開始使用它需要了解的東西。

我通常把我的資料庫配置放在 /config 資料夾,實體放在 /entities 資料夾。

  • 為什麼一篇文章涵蓋了所有這些庫?

這正是有趣的部分。

Routing-controllers 就像是你應用的地基。它給你輕鬆連線那兩個庫的可能(涵蓋在庫文件中)。當然,如果你不想的話可以不用。它可以和任何 ORM 一同使用。

但是,當你使用全部這三個庫時,你會讓框架對比其他解決方案時顯得太過強大(至少對我來說是這樣)。你有控制器,引數注入,body 注入,引數驗證,依賴注入,有了這些你可以忘掉手動提供依賴和定義型別,裝飾屬性的實體,查詢 builder。這全都是靠 TypeScript!所以,後端也將有編譯時型別檢查!

  • 是的,感謝涵蓋了那些功能的庫。但是再說一次,如何在 node 中使用 TypeScript?

好吧,這再簡單不過了。你可以像平時一樣寫 typescript,配置它編譯到 ES2015(node 現在有很多特性,不用把它編譯成 ES2015 之前的版本了),使用 CommonJS 標準來實現模組即可。

並且使用 pm2 或其他東西在編譯後啟動 index/server/app.js 。基本上生產程式碼已經就緒。不用 ts-node 或者其他什麼了。

如果你喜歡這些庫,不要忘了表達你的喜愛

如你所見,沒有很多人知道 routing-controllers 和 TypeDI,這些是我 TypeScript Node.js 專案用到的最強大並且好用的庫了。如果你喜歡它們,請花一秒鐘 star 它們並且宣傳一下。它們幫了我很多,所以我希望它們可以幫到你和其他同樣的 TypeScript 使用者!

這些庫也有 gitter 社群,你可以通過谷歌搜尋“gitter 庫名”很方便地找到它們。

感謝閱讀並且快樂地使用 TypeScript。歡迎評論或提問吧~


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章