- 原文地址:How to start with backend TypeScript and use it’s full potential.
- 原文做者:idchlife
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:xilihuasi
- 校對者:tvChan, noahziheng
我將從一個開發者的角度介紹幾個優秀的庫。它們能夠知足你後端應用的絕大部分特性。裝飾器和元數據的能力在這些庫中獲得的充分的應用,使其很是強大而且簡單易用。前端
我但願這篇文章能夠幫到像我這樣,喜歡 TypeScript 並且想用它編寫後端代碼的人,讓他們像我同樣發現這些庫以後樂在其中。node
TL;DR —— 堆棧使你的後端應用像許多使用其餘語言的企業靜態解決方案同樣強大:android
使用裝飾器,參數,body 注入的路由和控制器的庫ios
依賴注入和使用裝飾器的 services 的庫git
使用裝飾器的 ORM 就像 Doctrine/Hibernate 那樣方便操做實體github
給那些還不熟悉使用 TypeScript 寫後端的朋友的小建議typescript
Routing-controllers:控制器,行爲,請求等數據庫
pleerock/routing-controllers routing-controllers —— 建立結構化,聲明性和組織良好的基於類的控制器後端
儘管這個庫是做爲 Express/Koa 的 TypeScript helper 編寫的,它也會對你編寫控制器有所幫助,就像你在 Java/PHP/C# 的企業級框架裏用到的那樣。bash
下面是一個控制器的小例子:
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 插件)的例子:
如你所見,routing-controllers 甚至提供了 undefined 返回碼(也有 empty 和 null 的裝飾器)以及許多其餘特性。關於 this.playerService —— 這是另外一個迷人的庫,稍後我將介紹它。
整體來看,庫有強大的文檔,它能夠幫助你理解和構建適用於操做甚至整個控制器的自定義中間件的應用程序(這對我來講是個絕妙的時刻)。連接地址如你所見就在那,很是方便。
固然,你也可使用不少 Express/Koa 中間件把你的應用抽離出來,以及視圖配置(庫也有針對視圖的裝飾器),認證(能夠經過中間件應用到整個控制層),錯誤處理等方面的配置。
一般我把他們存放在 /controllers 文件夾。
TypeDI:依賴注入,services
這個庫幫我定好了項目結構,方便編碼而且不用去想「好吧 service 存在哪裏,這個是 service?唔或許是另外一個,可是,它怎麼依賴另外一個 service?怎麼引用其餘 service 唔。」
回到個人 PlayerService,下面這部分你能夠看到它依賴了什麼(其餘 services):
@Inject 對我來講是在處理 services 和邏輯完整的後端應用方面最好用的裝飾器。
(若是你想了解 @OrmEntityManager —— 另外一個來自 @pleerock 的庫,稍後我將講解)
是的,你能夠有不少 services 依賴其餘的 services。而且若是你有 service 循環依賴,你能夠經過明確地定義類型來解決這個問題(庫的文檔涵蓋了大部分的問題和情景)
對那些不熟悉 services,service 容器,services 依賴注入等的朋友。簡要說明:
你有某種功能,想把它存在類中,而後你想要類的實例而且想讓這個類依賴另外一個,另外一個等。service 容器的依賴注入能夠爲你保駕護航。你能夠從容器中獲取 services 而且它會本身處理 services 的全部依賴,給你帶有其餘實例的工做實例自動注入。
我關於這個庫的描述並不涵蓋它的全部潛能(你能夠本身查看它的文檔——有更多的特性可使用):你能夠在定義 services 時給它命名,還能夠定義構造器注入等。
一般我把個人 services 存放在 /services 文件夾。
TypeORM:使用 ORM 定義關係型實體,不一樣列類型和不一樣數據存儲方案很是方便(關係型,非關係型)
這給個人感受就是,用 TypeScript 寫 Node.js 最終有能力跟其餘語言和 ORMS 競爭。
強大的 ORM 可讓你很方便地用一種可理解的方式編寫實體。我不是其餘許多相似這種 Node.js ORMS 的粉絲:
module.exports = { id: SomeORM.Integer, name: SomeOrm.String({ …})}
複製代碼
我老是想讓實體寫成類。被賦予類型的屬性的類,會被帶有簡單裝飾器的 ORM 發現。甚至是沒有類型的。
TypeORM 給你這種能力。我項目中的另外一個例子:
如你所見,我甚至沒在裝飾器中寫屬性的類型(你能夠這樣作,不要擔憂,明確地定義類型,默認的,可空的等)!TypeORM 爲我作了全部這些工做,瞭解什麼類型(感謝 TypeScript 反射:元數據擴展功能)以及把它應用在個人數據庫。
它很是強大,你將擁有全部你在其餘 ORMs 中擁有/看到的東西,好比(Doctrine, Hibernate)。
當使用 routing-controllers 和 TypeDI,它會爲你注入實體管理器(就像你在個人 PlayerService 截圖中看到的同樣)提供很是有用的裝飾器或者鏈接你的控制器和 services(這很是方便)。
這個 ORM 有一個涵蓋了大量功能的官方文檔,你能夠看看而且從中瞭解全部你開始使用它須要瞭解的東西。
我一般把個人數據庫配置放在 /config 文件夾,實體放在 /entities 文件夾。
這正是有趣的部分。
Routing-controllers 就像是你應用的地基。它給你輕鬆鏈接那兩個庫的可能(涵蓋在庫文檔中)。固然,若是你不想的話能夠不用。它能夠和任何 ORM 一同使用。
可是,當你使用所有這三個庫時,你會讓框架對比其餘解決方案時顯得太過強大(至少對我來講是這樣)。你有控制器,參數注入,body 注入,參數驗證,依賴注入,有了這些你能夠忘掉手動提供依賴和定義類型,裝飾屬性的實體,查詢 builder。這全都是靠 TypeScript!因此,後端也將有編譯時類型檢查!
好吧,這再簡單不過了。你能夠像平時同樣寫 typescript,配置它編譯到 ES2015(node 如今有不少特性,不用把它編譯成 ES2015 以前的版本了),使用 CommonJS 標準來實現模塊便可。
而且使用 pm2 或其餘東西在編譯後啓動 index/server/app.js 。基本上生產代碼已經就緒。不用 ts-node 或者其餘什麼了。
若是你喜歡這些庫,不要忘了表達你的喜好
如你所見,沒有不少人知道 routing-controllers 和 TypeDI,這些是我 TypeScript Node.js 項目用到的最強大而且好用的庫了。若是你喜歡它們,請花一秒鐘 star 它們而且宣傳一下。它們幫了我不少,因此我但願它們能夠幫到你和其餘一樣的 TypeScript 使用者!
這些庫也有 gitter 社區,你能夠經過谷歌搜索「gitter 庫名」很方便地找到它們。
感謝閱讀而且快樂地使用 TypeScript。歡迎評論或提問吧~
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。