前後端互動-一些關於介面設計的思考
前言
最近在工作中和後端童鞋打交道,前後端溝通最為重點的就是介面API,這裡整理一下介面設計的一些考慮點並做分析,希望對大家有幫助 。
兵馬未動,糧草先行。在一款APP產品的各個版本迭代中,兵馬的啟動指的是真正開始敲程式碼的時候,糧草先行則是指前期的需求,互動,UI等評審準備階段,還有本文要說的介面的設計與評審。雖然很多時候一個api介面的業務,資料邏輯是後端提供的,但真正使用這個介面的是客戶端,一個前端功能的實現流程與邏輯,有時候只有客戶端的RD才清楚,從某種意義來說,客戶端算是介面的需求方。
所以建議在前期介面設計和評審時,客戶端的RD應該更多的思考和參與,什麼時機調什麼介面?每個介面需要哪些欄位?資料含義怎麼給?只有這些都考慮清楚,且達成一致併產出介面文件後,當專案真正啟動時,根據介面協議進行開發,才能儘量避免各種不確定因素對專案整體進度的影響。
介面設計的考慮點
我從下面幾個方面考慮介面的設計:
1 介面文件
2 介面安全
3 一些基本原則
4 瘦客戶端
1 關於介面文件
1.1 介面設計必須提供介面文件
無論專案團隊的大小,在遇到介面問題的時候單純的從程式碼出發,而不是從介面文件出發,對於整個專案團隊的維護簡直就是耍流氓。
1.2 文件也應納入版本控制
使用markdown,wiki 做文字型別的文件,使用svn,git等做為版本工具 可以很清晰的看到介面文件的改動人和改動時間,同樣是方便維護工作。
1.3 文件型別選擇markdown,wiki等
使用文字型別的文件(比如markdown, wiki等格式),一則方便比較版本間改動,二則可以生成html, word, pdf等多種美觀格式。我見過有好多團隊是使用word來寫文件的,由於是二進位制格式,不利於版本比較,也不專業。
1.4 文件- 簡潔
檔不應浮於形式,而是力求只寫最有價值的內容。做好這一點的關鍵是作者與讀者要有足夠的約定,比如蠶繭法就能很好的幫助簡化型別定義的描述。
1.5 應有機制保證介面文件與程式碼的一致
一些團隊在文件上應付差事浮於形式,在程式碼寫完後,補一個word文件應付。在更新程式碼時,文件沒有及時更新,導致文件都是錯誤沒法看。好的做法都應先有設計再寫程式碼,比如架構師或主程先設計好介面,然後再開始程式設計實現,在實現中發現問題再修正介面,更新設計文件,而不應是寫完程式碼再補個設計。而在文件更新的具體做法上,也流行一種做法即文件以註釋的方式內嵌於程式碼中,我稱之為“格式化註釋”,這樣做到設計與程式碼在一起,更新也就更自然的同步了。之後再通過工具將註釋抽出來美化給讀者看。
1.6 介面應當包含內容
介面地址、請求方法、請求引數、返回內容、錯誤程式碼
- 以下是一個使用者資訊介面的文件示例,包含介面描述,請求引數,響應引數,json示例等。
介面描述:使用者登陸成功後,或進入個人中心時會獲取一次使用者資訊
"code":200,
"msg":"成功",
"time":"1482213602000",
"data": {
"id":"1001",
"name":"張三",
"age":"20"
}
}
2 介面安全
當我們面對很多外部介面的時候,我們需要考慮資料的安全性。為什麼要考慮安全性:
- 包含使用者資料
- 包含交易資料
- 以及甚至你不想讓使用者自己知道的資料
所以分為請求引數和響應引數:
- 請求引數中包含使用者隱私的欄位引數,如:登陸介面的密碼欄位,需要進行加密傳輸,避免被代理捕捉請求後獲取明文密碼。
- 響應引數中包含使用者隱私的欄位資料,需要加*號。如:手機號,身份證,使用者郵箱,支付賬號,郵寄地址等。
"phone":"150*****000",
"idCard":"3500**********0555",
"email":"40*****00@qq.com"
}
- 客戶端和伺服器通過約定的演算法,對傳遞的引數值進行簽名匹配,防止引數在請求過程中被抓取篡改
保護介面的方式最基本的是SSL/TLS,然後呢:
- 對稱加密的方式
- 非對稱加密的方式
- 動態祕鑰
3 介面的一些原則
3.1 一個頁面儘量只有一個拉取介面
原先一個頁面要通過多個請求獲取多種型別資料的情況,最好能通過一個介面全部獲取得到。又如:在呼叫B介面前需要A介面的前置資料的情況,可以讓後端支援下,在呼叫A介面時直接返回B介面的資料,減少類似這種的連續請求。
3.2 打破第一條規則,當請求需要快取並且有需要及時更新的情況
為了更好的開啟速度,對於不經常變化的資料,往往需要做資料快取以及請求快取。但有些資訊,比如預約時間,又需要做到及時,則應該分多個請求。
3.3 如果返回資料中某個欄位的資料沒有,返回該欄位比不返回該欄位要好。
JSON格式的好處在於靈活性,但沒有校驗機制。所以定義協議時規定了有哪些欄位,最好這些欄位都返回。我的意思是比如返回一個列表,大多數場景是返回一個數組,但如果沒有資料,返回一個空陣列比不返回該欄位要好。當然前端也有必要做自己的容錯考慮。
比較常見的返回資料的格式:
3.4 命名規範
統一命名:與後端約定好即可(php和js在命名時一般採用下劃線風格,而Java中一般採用的是駝峰法),無絕對標準,不要同時存在駝峰”userName”,下劃線”phone_number”兩種形式就可以了。
避免冗餘欄位:每次在新增介面欄位時,注意是否已經存在同一個含義的欄位,保持命名一致,不要同時存在”userName”,”username”,”uName”多種同義字段。
註釋清晰(重要):每個介面/欄位都需要有詳細的描述資訊,很多時候介面體現業務邏輯,是團隊中很重要的文件沉澱,同時,詳細的介面文件,可以幫助新人快速熟悉業務。
3.5 將APP接收資料的型別定義為容錯能力更強的String(推薦)
容錯性強,規避因髒資料引起的資料解析失敗。
4 瘦客戶端
眾所周知,客戶端任何的修改都是需要發版的,特別是IOS需要走AppStore的稽核流程。為了修一個bug,僅僅改幾行程式碼,而重新走一輪發版流程,是很勞民傷財的。所以在介面設計的時候,也需要適當考慮這點,將業務重心交由後端,客戶端保持邏輯簡單。後端一天可以發n個版,客戶端一個版本卻只能發一次,有些團隊一開始並沒意識到這點,總覺後端就是重度業務邏輯的所在,管那麼多前端的展示,真正到了出問題(bug或需求變更)需要發版的時候,雖然70%的鍋是客戶端背,但是,剩餘30%也會對當初重客戶端的選擇而後悔,不過重點不是誰背鍋,而是產品不出問題。so,為了大局,後端的RD們,我們得聊聊。
4.1 客戶端儘量只負責展示邏輯,不處理業務邏輯
例如:客戶端有個TextView,後端只給個status欄位,status=1時,展示文案1;status=2時,展示文案2;這樣設計的缺點是,如果以後要修改status=3時,展示文案1,那麼這個status判斷邏輯時寫死在客戶端,就沒辦法支援這種修改,且這種設計限定死了TextView只能展示2種文案。推薦方案是後端直接將TextView需要展示的文案下發,這樣不管是status的判斷,還是文案的展示,後期都是可變的。
4.2 客戶端不處理金額的計算
例如:外賣APP,使用者在下單的時候,需要選擇收貨地址,支付型別,優惠券等,任何一個選項的修改,都可能影響使用者最後需要支付的金額。所以這裡比較常見的介面設計是在每次選擇完回到訂單支付頁面後,再發送一次請求,後端根據當前選項重新計算金額。金額永遠是一款產品最重要,最敏感的資訊,如果交由客戶端計算,萬一出錯,即使少1分,都是毀滅性的,所以,關於金額,展示就好。
4.3 客戶端少處理請求引數的校驗與約束提示
例如:修改密碼功能,密碼規則”6-12字母,數字,下劃線”,有3種做法:
- 1 在傳送請求前,客戶端校驗密碼規則,如果不符合,則不傳送請求。優點:規則不滿足時,可以減少不必要的請求。缺點:客戶端寫死校驗邏輯,密碼規則變化時,客戶端需要發版。
2 客戶端只判斷null,和最短位數限制,其他校驗規則交由後端處理。優點:靈活性最好。缺點:後端壓力大,校驗請求多。
3 後端在通用配置的介面返回正則表示式,客戶端獲取後進行正則校驗。優點:具有一定靈活性。缺點:開發,除錯成本較高。(推薦:即使出問題,也可以清除配置,回退到第2個方案)