### GDSC NYUST x 資訊創客社
<br>
### JS後端與資料庫讀書會
### tsoa with Express
<br>
#### 2023/12/06 ( Wed ) 19:00 - 21:00
#### 講師:蘇祐民 *YoMin Su*
#### 本次課程影片:(⚒️製作中)
<img src="" height="200px">
---
## 課程簡介
----
### 今天的目標
- 初始化JS專案
- 安裝所需要的套件
- 介紹tsoa
- 嘗試tsoa的CLI工具
- 基於上週的架構進行調整
- 透過tsoa設計路由
- 以tsoa生成Express使用的路由
- 以tsoa生成Swagger需要的json
- 在Express中整合SwaggerUI
- 啟動Express並驗證路由
---
## 開始前的準備
----
### 請先準備好上週最後的成果
1. 初始化專案
2. 安裝所需要的套件
3. 複製程式碼到專案中
4. 準備要開始嘍!
> [上週簡報點我](/@ji03mmy18/HyDqeGVB6#/6)
---
## tsoa
----
### 套件介紹時間
tsoa實際上是個縮寫,對應著TypeScript OpenAPI,主要的目標是為了讓開發者在設計API路由時,可以自動生產出對應的OpenAPI Doc所設計的套件,目前除了Express以外,也可以用於Hapi與Koa兩個不同的框架。而tsoa進行路由定義的方式,也簡化了開發上的困擾,使前後端可以基於一份有用的文件進行溝通,減少開發的成本!
<div style="background-color: white">
<image src="/_uploads/r1VhQ3THp.png" width="400" /> <image src="/_uploads/H14NEnaHa.png" width="250" />
</div>
----
### 該如何安裝呢?
按照官方的說明文件表示:
```bash=
yarn add tsoa express
yarn add -D typescript @types/node @types/express
```
----
### 加入tsoa.json
這是tsoa的設定檔,用於讓CLI工具知道該到哪裡找到我們的程式碼,範例如下:
```json=
{
"entryFile": "src/app.ts",
"noImplicitAdditionalProperties": "throw-on-extras",
"controllerPathGlobs": ["src/controller/*.ts"],
"spec": {
"outputDirectory": "build",
"specVersion": 3
},
"routes": {
"routesDir": "build",
"iocModule": "src/ioc.ts"
}
}
```
----
### 額外的小改進
tsoa除了自己的設定值以外,也推薦將tsconfig.json調整成下面的設定:
```json=
{
"compilerOptions": {
/* Basic Options */
"incremental": true,
"target": "es6",
"module": "commonjs",
"outDir": "build",
/* Strict Type-Checking Options */
"strict": true,
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictBindCallApply": true,
"strictPropertyInitialization": true,
"noImplicitThis": true,
"alwaysStrict": true,
/* Additional Checks */
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
/* Module Resolution Options */
"moduleResolution": "node",
"baseUrl": ".",
"esModuleInterop": true,
/* Experimental Options */
"experimentalDecorators": true,
// emitDecoratorMetadata is not needed by tsoa (unless you are using Custom Middlewares)
/* Advanced Options */
"forceConsistentCasingInFileNames": true
}
}
```
----
### 來確認一下DI容器的設定
在剛剛的設定中,我們有跟tsoa說要到哪裡尋找我們的ioc模組,因此,讓我們來修改一下原本的變數命名,配合tsoa使用:
```typescript=
import { Container } from "inversify";
import { db } from "./db";
import { route } from "./routes";
const iocContainer = new Container();
iocContainer.bind<db>(db).to(db);
iocContainer.bind<route>(route).to(route);
export { iocContainer }
```
---
## 來寫路由吧!
----
### 建立對應的物件
首先會針對同類型的路由建立一個分類,在程式碼中以物件的方式呈現:
```typescript=
export class DefaultController {
constructor() {}
public async getRoot() {}
}
```
----
### 來加上對應的裝飾器
```typescript=
@Tags('Default collect')
@Route('default')
export class DefaultController extends Controller {
constructor(
@inject(db) private _db: db,
) {
super();
}
@Get('')
public async getRoot() {
return {
status: true,
data: await this._db.getStudent(),
}
}
}
```
----
### 來透過tsoa生成需要的檔案
此步驟要透過CLI輸入指令來進行,操作如下:
```bash=
yarn tsoa spec-and-routes
```
<br />
接著,請看看有沒有出現build資料夾呢?
----
### 檔案說明

- routes.ts: 這是用來給Express註冊的路由
- swagger.json: 這是用來顯示Doc使用的定義
----
### 修改存放路徑
因為在使用上,還需要進行編譯,因此,我們修改一下tsoa.json的設定:
```json=
{
"spec": {
"outputDirectory": "src"
},
"routes": {
"routesDir": "src",
}
}
```
----
### 將生成的內容註冊到Express中
在繼續之前,要來增加另一個套件,用於渲染Swagger.json
```bash=
yarn add swagger-ui-express
yarn add -D @types/swagger-ui-express
```
----
### 將生成的內容註冊到Express中(2)
接著則是將原本app.ts中建立diContainer的部分替換為tsoa產生的內容:
```typescript=
export default async function appInit(): Promise<Express> {
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
console.log("Parse JSON");
createDataSource();
await initDataSource();
console.log("DataSource Init");
const path = "./swagger.json";
const swaggerJson = await import(path);
app.use("/api/docs", swaggerUi.serve, swaggerUi.setup(swaggerJson));
const tsoaRouter = await import("./routes");
tsoaRouter.RegisterRoutes(app);
return app;
}
```
----
### 編譯時間
請輸入以下的指令進行編譯:
```bash=
yarn tsc
```
<br />
這時的build資料夾內應該會出現許多js檔案,且檔名與你的ts對應~
----
### 嘗試執行看看!
請使用:
```bash=
node build/server.js
```
> 資料庫有記得啟動嗎~
----
### 你的Swagger!

{"title":"tsoa with Express","description":"PostgreSQL 入門","contributors":"[{\"id\":\"f8142aa2-66aa-4867-821d-2f1ffff7a7ba\",\"add\":4777,\"del\":19}]"}