關於介面設計的一些反思

週週zzz發表於2020-07-29

許久沒有產出了,今天看了掘金上的一篇關於介面設計的文章,因此有感談談自己在專案開發中與後的一些想法和反思。

參考:一篇來自前端同學對後端介面的吐槽

以使用者的視角開發介面

對於RESTful風格的前後端分離式開發,介面的設計應該從何種視角出發呢?一般情況下,後端開發人員(我)的想法是:

  1. 想要實現這個功能,我需要返回哪些資料?
  2. 我要怎樣劃分不同的API?
  3. 當兩個介面返回的資料有重複的部分時,我是否需要做一些複用?
  4. ...

在這種視角下,我開發出的介面雖然實現了專案的需求,但是卻可能與其在前端的易用性產生割裂。

一個例子

在我之前獨立開發的一個資料視覺化系統中,存在著這樣一個功能:

該專案的資料存在四種層級:team、group、branch、total,這四個層級的資料項都是一樣的,現在需要提供介面分別返回這四個層級的資料。

實際開發中,資料庫中存在著四張資料表,而我不想使用MyBatis的${}以字串拼接的形式來生成SQL,於是我寫了四個邏輯幾乎完全相同的Service類,最終反映到Controller上,就是每個層級的資料都有一個API去獲取資料。當然,後端這裡應該有更好的處理方式,不過暫且按下不表。當我終於大致完成後端的介面設計,轉而開發前端時,才發現我介面設計的不合理之處。首先,前端要配置多個axios,其次,傳送請求時,前端需要編寫多餘的程式碼去選擇要呼叫哪個API,同時,我在後端的swagger2除錯頁面也臃腫不堪。

現在想起來,這裡的“層級”不應作為API劃分的依據,而應當作為獲取資料這個API的一個引數。在開發過程中,我僅僅是看了一下資料表的劃分就匆忙開始了介面的設計與開發,而忽略了它還應當儘可能為使用者服務,這讓同時兼任前端開發的我在後來吃到了苦頭。實際工作中,開發出這樣的介面吃到的可能就是前端開發的磚頭了。

資料格式

目前我注意到的介面開發中可能需要額外處理的資料主要有:

時間

Java中後端直接返回的時間格式一般形如:2020-07-29T00:00:00.000+0800;

而前端需要展示的格式一般為:yyyy-MM-dd HH-mm-ss

對於返回日期的格式轉換我認為放在前端來做比較好,因為前端在不同的地方可能需要對日期進行不同的格式化。如果後端返回格式化好的字串那前端仍然需要進行一些額外的操作。步驟多一點出bug的機率也會大一點。

對於請求的日期,一般是傳字串,後端進行解析。不知道有沒有直接傳日期型別的方法呢?每個介面都要解析一次日期字串還挺麻煩的。順帶一提,swagger中可以通過傳Wed, 29 Jul 2020 00:00:00GMT形式的資料直接識別為Date型別。

百分數

對於“67.2%”這一條資料,前後端的處理方案分別有:

  • 前端:0.672、67.2
  • 後端:0.672、67.2、"67.2%"

這裡的資料格式一般有根據前後端的約定來,感覺沒有太大影響。

金額數

由於後端double運算的特性,金額一般使用以分為單位的Integer型別或bigInteger計算。同理,前後端互動的金額資料也應使用整型。最近做一個支付介面的測試時發現他們的金額引數確實就是string(以分為單位)。

HTTP狀態碼

關於HTTP狀態碼,我一直都有些困惑。一般來說,我們返回的一個response中,會同時包含HTTP status和自定義的業務code等資訊。例如我在自己專案中封裝的統一返回結果:

{
  "timestamp": "2020-07-29T00:00:00.000+08:00",
  "code": 200,
  "message": "success",
  "data": 123,
  "path": "/result"
}

HTTP狀態碼代表這次請求的結果,而自定義的code以及message代表業務的結果。那麼對ForbiddenUnauthorized等情況,我們是否應該同時修改HTTP statuscode呢?如果是的話,那麼這兩個標識看上去就有了冗餘,沒有很好地做到“各司其職”,雖然這並不影響整個系統的執行,但是我總在想這方面會不會有更合適的實現方式。

相關文章