iT邦幫忙

2023 iThome 鐵人賽

DAY 14
0

經過前面的鋪陳水文,相信大家對於如何將 FP 應用在 Next.js 的表單驗證已經有一定的了解。不過表單驗證畢竟只是同步的操作,在網頁環境下,我們有許多異步/非同步的操作要處理。

https://ithelp.ithome.com.tw/upload/images/20230929/20158615eWwQzaW0hf.png

以最下方的 新增使用者功能為例,整體流程還是可以參考一路走來始終如一的這張圖。

  1. 使用者輸入要新增的使用者名稱 後按下 Add 觸發 ui event 後轉成 react event
  2. react event 經過 function A 轉換成 domain type 也就是使用者列表
  3. 把使用者列表存到 Atom
  4. 把使用者列表經過 function B 傳遞給 UserBadge 子元件,經過渲染後看到新的 UserBadge

回想九天前 D05 - 設計工作流程的流程真的非常簡單! 然而接下來的內容如果還是這麼簡單那就真的太水了那就太沒挑戰性了,所以我們將看到一個複雜很多的流程圖 !

https://ithelp.ithome.com.tw/upload/images/20230929/20158615fcqTm0KaZe.png

異步請求回應工作流程說明

https://ithelp.ithome.com.tw/upload/images/20230929/20158615UeFG97IfgH.png

  1. 把使用者事件轉換為方便發送請求的資料格式,如果 API 設計對前端足夠友善,或是請求非常簡單,這個步驟可以忽略不做。

    以設定使用者這個功能來說,使用者事件中的資料就是要新增的使用者名稱,這本身就是字串,已經非常方便發送請求了,所以我們不必再多做轉換。

  2. 把請求打去給後端伺服器。

    從古至今有封裝 XHRjQuery ajaxaxios ,還有原生的 fetch,只要能把請求打出去其實用什麼都行,不過我還是比較偏好 axios ,所以後面的實作還是會使用 axios

  3. 後端,也就是 Next.js 的 API 服務收到請求後,不可以理所當然的覺得請求都是對的,必須謹慎的對請求內容執行驗證,確保請求符合 API 制定的格式,或是授權、身分驗證沒有問題。如果格式錯誤就要把流程導向錯誤的軌道。

    使用者輸入可以做各種限制,例如不得小於 3 字,不得大於 100 字,這些限制不只前端做,後端更要做,因為我們無法保證對方只能透過 UI 發出請求,總不能任何一個有技術背景的人捏一個不合格的請求就能摧毀我們的服務。

    忘記甚麼是錯誤的軌道? 請回顧 D07 - 軌道驅動設計

  4. 確保請求格式正確後,發出請求與更後面的外部資源溝通,這裡我們會以 MongoDB 為範例,並取得可能正確、可能錯誤的結果(例如資料庫連線異常),這邊同樣會用到軌道驅動設計的概念來做錯誤處理。

    以設定使用者這個功能來說,就是去資料庫查詢有沒有這個人。

  5. 根據前面可能出現的 請求格式錯誤、驗證錯誤、授權錯誤、後端錯誤,或是正確結果,決定該傳給前端的回應是甚麼,通常會用狀態碼代表,例如 200 沒問題、400 請求格式錯誤、404 找不到、500 代表資料庫等等內部問題。

    如何做錯誤處理可以參考 D11 淺談型別安全 中的模式配對

  6. 成功取得回應之後,前端不應該把收到的回應「當作」某一種型別,仍然要對回應進行驗證,這時候有驗證就會有可能出現驗證錯誤。除了驗證錯誤以外,通常我們也會把 4XX、5XX 的狀態碼轉當作錯誤來處理。

    根據軌道驅動設計的模式,如果發生請求錯誤,步驟 6 會被略過,因為這時候火車已經開去錯誤的路了

  7. 不論是發生錯誤或是得到正確結果,我們都要對所以可能發生的狀況進行適當的處理,處理方式視需求而定,例如在 UI 上提醒使用者,或是把使用者導向登入頁面,甚至有時候不處理也是一種處理方式。

    如何做錯誤處理同樣可以參考 D11 淺談型別安全 中的模式配對


接下來幾天會搭配程式碼解釋如何完成以上流程 !

https://ithelp.ithome.com.tw/upload/images/20230929/20158615PFmMIMf85X.png
來源


上一篇
D13 - 實作依賴注入
下一篇
D15 - 實作異步流程 (一)
系列文
從 Next.js 開始的 Functional Programming30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言