Day 24 - 利用 Interceptor 處理 Token
當我們在開發一個完整的應用程式時,不管是 App 或者是 Web,通常會需要拿著 Token 去問 API,然後才能拿回想要的資料。在這個過程中,無可避免的是,Token 會有失效的時候,此時我們會再去跟 API 要一個新的 Token,然後才打 API。

依舊是職責的問題
在上面這段程式碼中,我們可以發現 get 方法中,不僅處理了 Token 的更新,也處理了 Response 的解碼,兩份工作被同時塞在小小的 get 方法中。我們可以透過抽取方法來解決,讓 get 方法只負責控制流程,把工作交給其他方法。

也可以使用昨天的文章中提到的裝飾者模式,將 Token 更新的職責放到 TokenDecorator 中,讓 TokenDecorator 去負責 Token 的維護,而 HttpProviderImpl 就能專注在呼叫 API 的工作上。

除了自己實作裝飾者模式之外,許多呼叫 Web API 的相關套件,都有提供類似的功能,讓我們不必重造輪子。
使用 Interceptor
當今天大家使用 http 套件作為呼叫 Web API 的選擇時,我們可以再加上 http_interceptor,為 http 套件外掛上 interceptor 的功能。

當今天任何使用端發出任何 Request 時,都會走近 interceptRequest 方法,此時我們有機會檢查 Token 是否過期,並在適當時機更新 Token,然後程式就會穿過 interceptor 呼叫 API。

相比於自己實現裝飾者模式,使用套件的 Interceptor 功能,能讓我們有機會處理每個 Request 的 header。在上面的程式碼中,我們也可以直接在 Interceptor 把 token 放進 header 中,這樣一來 HttpProvider 也可以避免自已處理 token,讓職責分工更明確。

除了 Token 之外
使用 Interceptor,我們不只能處理 Token,我們也能處理各式各樣的通用邏輯,例如:Logging 或者是 Caching。將不同的職責分配到不同的 Interceptor 也是實現 AOP 的一種方式。
不只 http 套件有 Interceptor
在開發 Flutter 時,除了可以使用 http 來呼叫 Web API 之外,還有 dio 套件也是熱門選項之一。相比於 http 套件,dio 套件本身就自帶有 interceptor 的功能。我們修改一下上面的例子,再看一下程式碼,就會發現他們其實十分相似。

結論
大多時候,客端程式或多或少,都會需要呼叫 Web API 來取得一些後端資料。我們也常常需要使用 Token 來向後端證明自己合法的使用者,在使用 Token 的過程中,利用裝飾者模式或者 Interceptor 將 Token 管理的職責從實際呼叫 API 的地方分離,除了能讓程式碼職責更明確之外,也讓其符合開放封閉原則。