這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。**摘要**:*在實現一個服務或 API 時,如果你收到一個你不太理解的請求,最友好的方式就是返回一個錯誤資訊。*讓我們來考慮這樣一個 API:`GET /mySum?num=3&num=42`非常簡單,是不是?我可能會這樣來實現它:```gofunc mySum(args url.Arguments, w http.ResponseWriter) {w.Write(int(args["num"][0]) + int(args["num"][1]))}```等一下:如果收到一個額外的參數 `foo` 應該怎麼辦?一個常見的做法就是忽略它:*我們常常會讓我們的 API 對請求中它所理解的部分做儘可能多的事,以此來讓 API 發揮作用。* 在這個簡單的例子中,忽略 `&foo=bar` 這樣一個額外的參數看起來並沒有什麼影響。但是,如果收到了第三個 `num` 參數該怎麼辦?這在更大程度上是一個灰色地區:按照前面的實現這個參數將直接被忽略。然而調用者很合理的可能預期這個參數也被包含在最終的加和中。在這個服務中我們沒有對傳入的參數進行校正,這帶來了一個調用者不易發現的 bug,它是最糟糕的 bug 類型:***無提示故障***(Silent failures)。無提示故障很*可怕*。它們讓我夜間盜汗。他們可能會潛伏很長時間都不被偵測到,甚至是無限期的:在此期間我們認為一切都沒問題。這種故障的排錯是非常棘手的,因為它們是無提示的。它們帶來了很高的,可能意味著真金白銀的機會成本。更糟糕的是,當 API 的複雜性增加,*特別是*當服務之間出現互相依賴,無提示故障帶來的影響將更難去分辨,也會傳播更廣。這是一個複合的問題。相比大量的錯誤記錄檔、段錯誤、異常,甚至是面向客戶的錯誤,無提示故障是我們最不願意麵對的。對此我們該做什麼呢?在此我想介紹一個非常有用的模式,這個模式在構建可信賴的,避免無提示故障的服務時非常有用:(1) 給參數以明確的表示。通常,Thrift RPC 或者 gRPC 可以很好的幫你。對於 mySum API,我們將有這樣的結構:```gotype MySumParams struct {Lhs, Rhs int}```(2) 編寫*校正器*來檢驗參數是否符合它的類型在語義上的預期。例如,如果 MySumParams 只接受正數,那麼它應該定義一個 `Validate()` 函數,當接收到的參數不是正數,返回一個有意義的錯誤資訊。在 go 的程式碼程式庫中,對於這些檢驗器,我們有一個指定的函數簽名:`func Validate() error`。*認真地考慮*為每一個 Thrift RPC 或 gRPC 類型定義一個校正器。通過保證用戶端和伺服器不會出現不一致的預期,這增加了很大的安全性。而這些不一致的預期,往往在服務有修改或者更新時容易出現(例如,我們之後可能將 `mySum` 修改為允許參數為負)。對於 REST API 來說,校正器應當與參數的傳遞和提取解耦,因為他們關心的是不同角度,分開也更加容易測試。(3) 一旦參數被解析出來,將它們從請求的參數列表中刪除。Thrift 和 gRPC 傾向於幫你管理這一切,但是例如對如下的 REST API:```gofunc extractMySumParams(args url.Arguments) MySumParams {var result = MySumParams{Lhs: args["num"][0],Rhs: args["num"][1],}// Strip consumed num arguments.args["num"] = args["num"][:2]}```我可能會在使用 `extractMySumParams` 的同時,也使用一些與它沒有任何關係的參數提取器,這些提取器也會從 `args` 中彈出參數。然而,當我的 API 解析並驗證了所有的參數,我就可以斷言 `args` 已空(如果非空,應當返回 error)。將參數的處理分解為提取、驗證、斷言這幾個單獨的步驟被證明是非常有協助的,可以協助我們儘早的捕捉到問題,並快速地定位問題的根源。— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —*這篇文章作者是 John Graettinger, 我們紐約辦公室的開發架構主管。這是由 LiveRamp Team Dev推出的關於最佳實務的周五有感系列的一部分。你喜歡一直追尋自身提升的Team Dev嗎?[我們一直在招聘](https://liveramp.com/careers/engineers/)*
via: https://medium.com/@LiveRamp/friday-thoughts-fail-fast-and-furiously-26705b55fbcc
作者:LiveRamp 譯者:krystollia 校對:rxcai
本文由 GCTT 原創編譯,Go語言中文網 榮譽推出
本文由 GCTT 原創翻譯,Go語言中文網 首發。也想加入譯者行列,為開源做一些自己的貢獻嗎?歡迎加入 GCTT!
翻譯工作和譯文發表僅用於學習和交流目的,翻譯工作遵照 CC-BY-NC-SA 協議規定,如果我們的工作有侵犯到您的權益,請及時聯絡我們。
歡迎遵照 CC-BY-NC-SA 協議規定 轉載,敬請在本文中標註並保留原文/譯文連結和作者/譯者等資訊。
文章僅代表作者的知識和看法,如有不同觀點,請樓下排隊吐槽
324 次點擊