關於接口設計的一些反思


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

參考:一篇來自前端同學對后端接口的吐槽

以使用者的視角開發接口

對於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呢?如果是的話,那么這兩個標識看上去就有了冗余,沒有很好地做到“各司其職”,雖然這並不影響整個系統的運行,但是我總在想這方面會不會有更合適的實現方式。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM