在介紹 Middleware 前,先來說為什麼需要統一回傳格式,如果沒有統一格式會發生什麼事情,我們一一將優缺點列下來:

(1) 沒有統一格式:

  • 凌亂不統一,Client 在接回傳資料時不好處理。
  • 沒有統一回傳狀態類(Code/ErrorMessage)的欄位只回傳資料,當 Client 收到空物件或例外時難以判斷問題。
  • 後期需要多加狀態欄位麻煩,例如每支 API 各自加狀態欄位容易亂,如果要抽共用還要考慮資料的結構或階層被改變對 Client 的影響。

(2) 統一格式:

  • 明確回傳狀態類(Code/ErrorMessage),對 Client 來說遇到問題容易釐清方向。
  • Client 需要花時間判斷回傳狀態類(Code/ErrorMessage),各代表的內容與意思。

那要怎麼在專案內統一回傳格式呢?我們可以在 Middleware (中介層) / Filter (篩選器) 中進行改動,這兩個看似沒什麼差別,其實執行順序還有負責的工作有一點差異,Middleware 是專案對 HTTP 請求跟回應的處理,而專案的 Action 執行前後就會有不同的 Filter 來處理請求跟回應,Filter分為以下幾種:

(1) Authorization Filter:最先被執行到,用來驗證請求是否合法,若為否就會跳過後面的步驟。

(2)Resource Filter:執行時間在 Authorization 之後和剩下的 Filter 都執行完之後。通常用來處理快取或模型繫結。

(3) Action Filter:在 Action 前後執行,通常用來處理傳入 Action 的參數和回應的結果。

(4) Exception Filter:處理應用程式中沒有被處理 (Catch) 的例外。

(5) Result Filter:應用程式執行無誤後就會執行。

而 Middleware 相對自由一點,以圖(圖一)來說雙方被使用到的順序會是長這樣:

圖一 執行順序

我們先將 ResponseHandleMiddleware.cs.cs 檔案建立基本架構(可以自行決定放在哪一個資料夾內,這裡示範是開一資料夾名為Middleware),並在 Startup 中的 Configure 啟用 Middleware 服務,這裡有兩種寫法:

(1) 在 Startup 中的 Configure 啟用 UseMiddleware<你的Middleware名>。

(2) 也可以選擇包一層 IApplicationBuilder 的擴充方法,客製啟用中介程序。

在來我們定義統一回傳的物件格式,通常裡面包含是否成功 / Http Code / Message / Data ….等。

在 Middleware 的 Invoke 可以獲取到 HttpContext,當失敗時不需要額外處理要回傳的物件,只需要將 Http Code 與 ErrorMessage 回傳給 Client,在回傳錯誤訊息時,可以將常用的錯誤訊息參數化(放入資源檔內)以利將來使用,建立 Message.resx 檔案寫入常用的參數,在專案內呼叫。

反之如果為成功時,則需要處理要回傳 HttpContext 內 Response 的物件,而在這裡的型別為 Stream,我們需要將 Stream 的內容轉為字串回傳並將 Http Code 與 ErrorMessage 回傳 Client。

這時就可以啟用 Swagger 在未輸入 JWT 時呼叫 API,會獲得錯誤的統一回傳格式(圖一),如通過 JWT 後呼叫 API,則會獲得正確的統一回傳格式(圖二)

圖一 Swagger
圖二 Swagger

到這裡統一回傳格式就處理好了,下一篇將會對 Model 進行驗證,可以驗證哪些內容?我們下一篇見~

--

--