1. 程式人生 > 其它 >☕️【系統設計】如何設計出優雅且實用的 API 介面

☕️【系統設計】如何設計出優雅且實用的 API 介面

記得最開始的時候在設計介面的時候規範還沒有那麼多,因為前後端還沒分離。不管是前端還是後端都是一個人開發,為了追求"效率"。所謂的介面規範百花齊放,各有各自的一套。後來前後端分離,哪些為了追求"效率"而寫的程式碼,重構起來的程式碼也是頭疼。

所以到了現在已經基本固定基本的機構體系,針對業務得不同還可以垂直拓展。

如何構建這幾個部分每個公司要求都不同,沒有什麼“一定是最好的”標準,但一個優秀的後端介面和一個糟糕的後端介面對比起來差異還是蠻大的,其中最重要的關鍵點就是看是否規範!

在設計介面時,有很多因素要考慮,如介面的業務定位,介面的安全性,介面的可擴充套件性、介面的穩定性、介面的跨域性、介面的協議規則、介面的路徑規則、介面單一原則、介面過濾和介面組合等諸多因素。

本文主要針對介面返回引數結合一些網上的案例比較和思考,來講述介面返回引數需要怎麼設計更加合理。

行業案例

- 簡書

這可能是我看到過最差的設計,開啟幾個網頁可以看到介面返回引數設計,簡單粗暴,這裡就不錯過多的評論。

{   // 結果集}

- 掘金

看完簡書再看下另外一個產品掘金,掘金相對而言會好點。至少有了明顯的層次結構,包含狀態碼、結果集、成功或錯誤,但是這個命名確實讓人有點誤解,至少我個人看到後是這種感覺。

{  "data":"結果集",  "err_msg":"成功或錯誤提示",  "err_no":"狀態碼"}

- CSDN

就論介面引數 CSDN 算是中規中矩的介面,介面包含了三大要素:狀態碼、結果集、成功或錯誤的的提示。

{  "code":"狀態碼/結果編碼",  "data":"結果集/資料",  "message":"成功/錯誤提示"}

針對這種返回引數針對單體服務來講算是合格的,知道每個介面的狀態、對應狀態的結果、針對狀態如果要展示提示可以根據 message 對應的資訊來確定。對於單體服務這種設計基本能滿足要求。

- InfoQ

看到 InfoQ 的介面返回值,讓我覺得不錯的一點就是有一個拓展的返回引數設計,裡面有個引數 cost(成本),通熟一點就是介面的耗時。

{  "code":"狀態碼/結果編碼",  "data":"結果集/資料",  "error":"成功/錯誤提示",  "extra":{    "cost":"成本/耗時",    "request-id":"請求ID"  }}

針對 InfoQ 的介面返回引數設計,相對上述幾個產品而已確實優化了很多,尤其是針對介面做了成本/耗時統計。但是這種設計還是有點冗餘,為什麼這麼講呢?因為瀏覽器自帶功能

對於 request-id 個人理解為當前請求執行緒的鏈路 ID。在微服務體系中用於追蹤服務的日誌,算是一把利器。

設計優化

結合上面幾個產品的介面返回引數設計,可以簡單歸納介面返回引數的幾個要點

在結合 InfoQ 和 CSDN 的基礎上,加上了 boolean 型別的是介面執行是否成功的標識,當然也你也可以用狀態碼,但是這裡做了一些的優化調整。

再思考一下一種常見國際化問題

  • 如何統一國家化提示?針對後端的一些校驗異常丟擲提示怎麼處理國際化問題?

其實解決上訴問題國際化問題不是特別難,稍微做一下調整。

  • code 調整為:成功/錯誤的 messageKey,由前後端統一約束國際化的 key

  • msg 調整為:成功/錯誤的提示資訊,由後端根據國際化配置轉化成對應的錯誤資訊

{    "success": true,    "code": "return.optSuccess",    "msg": "您的操作已成功!",    "data": {        // 資料    },   "extendProps":{        // 拓展   }}

  

設計拓展

在基礎返回資訊中針對拓展的補充,其實這裡的目的主要是對於開發和運維人員來補充的。

思考下如果一個介面返回了錯誤資訊,你的第一反應是怎樣的?

檢視後端日誌,但是日誌採集資訊那麼多,基於什麼資訊去查後臺伺服器的日誌才能快速定位問題?

為了解決日誌查詢難定位的場景,這裡建議加上鍊路 ID 也可稱為追蹤 ID,因此可以繼續優化設計

{    "success": true,    "code": "return.optSuccess",    "msg": "您的操作已成功!",    "data": {        // 資料    },    "traceId":"1fbovmc1hwu2wc5w2n2n4gm2lmjaoo2b5dw0"}

當然並不是所有的錯誤都需要去檢視日誌,必要的時候針對一些錯誤,後端開發完全可以將堆疊資訊快取丟擲來,例如這樣

{    "success": false,    "code": "初始化發生異常!",    "traceId": "1fbqterqbwu5wiow1bjvu6214amgrd3i7cw0",    "errStacks": [        {            "app": "base-service",            "code": "error.data.dictionary.conversion",            "message":"資料字典序列化異常"        }    ]}

針對介面看到堆疊資訊大致可以定位到自己程式碼錯誤的位置,如果還定位不到就要通過鏈路 ID 檢視後具體錯誤位置,因此針對介面返回引數可以繼續優化

總結

網際網路工程的高速發展,分散式、微服務、容器化架構的流行,網際網路已全面進入雲原生時代。構建系統的方式由最初的單體大應用演變為分散式架構,不以規矩,不能成方圓。只有我們不斷地去優化才會創造出更好的產品。本期主要針對介面返回引數結合一些網上的案例比較和思考。

其實在設計介面時,有很多因素要考慮,如介面的業務定位,介面的安全性,介面的可擴充套件性、介面的穩定性、介面的跨域性、介面的協議規則、介面的路徑規則、介面單一原則、介面過濾和介面組合等諸多因素。後期幾期會逐一分享。