symfony api 错误响应_如何设计一个牛逼的 API 接口
生活随笔
收集整理的這篇文章主要介紹了
symfony api 错误响应_如何设计一个牛逼的 API 接口
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
在日常開發中,總會接觸到各種接口。前后端數據傳輸接口,第三方業務平臺接口。一個平臺的前后端數據傳輸接口一般都會在內網環境下通信,而且會使用安全框架,所以安全性可以得到很好的保護。這篇文章重點討論一下提供給第三方平臺的業務接口應當如何設計?我們應該考慮哪些問題?主要從以上三個方面來設計一個安全的API接口。
????//?根據業務需求進行添加
????SUCCESS(200,"處理成功"),
????ERROR_PATH(404,"請求地址錯誤"),
????ERROR_SERVER(505,"服務器內部發生錯誤");
????
????private?int?code;
????private?String?message;
????
????CodeEnum(int?code,?String?message)?{
????????this.code?=?code;
????????this.message?=?message;
????}
????public?int?getCode()?{
????????return?code;
????}
????public?void?setCode(int?code)?{
????????this.code?=?code;
????}
????public?String?getMessage()?{
????????return?message;
????}
????public?void?setMessage(String?message)?{
????????this.message?=?message;
????}
}
????private?static?final?long?serialVersionUID?=?793034041048451317L;
????private?int?code;
????private?String?message;
????private?Object?data?=?null;
????public?int?getCode()?{
????????return?code;
????}
????public?void?setCode(int?code)?{
????????this.code?=?code;
????}
????public?String?getMessage()?{
????????return?message;
????}
????public?void?setMessage(String?message)?{
????????this.message?=?message;
????}
????public?Object?getData()?{
????????return?data;
????}
????/**
?????*?放入響應枚舉
?????*/
????public?R?fillCode(CodeEnum?codeEnum){
????????this.setCode(codeEnum.getCode());
????????this.setMessage(codeEnum.getMessage());
????????return?this;
????}
????/**
?????*?放入響應碼及信息
?????*/
????public?R?fillCode(int?code,?String?message){
????????this.setCode(code);
????????this.setMessage(message);
????????return?this;
????}
????/**
?????*?處理成功,放入自定義業務數據集合
?????*/
????public?R?fillData(Object?data)?{
????????this.setCode(CodeEnum.SUCCESS.getCode());
????????this.setMessage(CodeEnum.SUCCESS.getMessage());
????????this.data?=?data;
????????return?this;
????}
}
一 安全性問題
安全性問題是一個接口必須要保證的規范。如果接口保證不了安全性,那么你的接口相當于直接暴露在公網環境中任人蹂躪。1.1 調用接口的先決條件-token
獲取token一般會涉及到幾個參數appid,appkey,timestamp,nonce,sign。我們通過以上幾個參數來獲取調用系統的憑證。appid和appkey可以直接通過平臺線上申請,也可以線下直接頒發。appid是全局唯一的,每個appid將對應一個客戶,appkey需要高度保密。timestamp是時間戳,使用系統當前的unix時間戳。時間戳的目的就是為了減輕DOS攻擊。防止請求被攔截后一直嘗試請求接口。服務器端設置時間戳閥值,如果請求時間戳和服務器時間超過閥值,則響應失敗。nonce是隨機值。隨機值主要是為了增加sign的多變性,也可以保護接口的冪等性,相鄰的兩次請求nonce不允許重復,如果重復則認為是重復提交,響應失敗。sign是參數簽名,將appkey,timestamp,nonce拼接起來進行md5加密(當然使用其他方式進行不可逆加密也沒問題)。token,使用參數appid,timestamp,nonce,sign來獲取token,作為系統調用的唯一憑證。token可以設置一次有效(這樣安全性更高),也可以設置時效性,這里推薦設置時效性。如果一次有效的話這個接口的請求頻率可能會很高。token推薦加到請求頭上,這樣可以跟業務參數完全區分開來。1.2 使用POST作為接口請求方式
一般調用接口最常用的兩種方式就是GET和POST。兩者的區別也很明顯,GET請求會將參數暴露在瀏覽器URL中,而且對長度也有限制。為了更高的安全性,所有接口都采用POST方式請求。1.3 客戶端IP白名單
ip白名單是指將接口的訪問權限對部分ip進行開放。這樣就能避免其他ip進行訪問攻擊,設置ip白名單比較麻煩的一點就是當你的客戶端進行遷移后,就需要重新聯系服務提供者添加新的ip白名單。設置ip白名單的方式很多,除了傳統的防火墻之外,spring cloud alibaba提供的組件sentinel也支持白名單設置。為了降低api的復雜度,推薦使用防火墻規則進行白名單設置。1.4 單個接口針對ip限流
限流是為了更好的維護系統穩定性。使用redis進行接口調用次數統計,ip+接口地址作為key,訪問次數作為value,每次請求value+1,設置過期時長來限制接口的調用頻率。1.5 記錄接口請求日志
使用aop全局記錄請求日志,快速定位異常請求位置,排查問題原因。1.6 敏感數據脫敏
在接口調用過程中,可能會涉及到訂單號等敏感數據,這類數據通常需要脫敏處理,最常用的方式就是加密。加密方式使用安全性比較高的RSA非對稱加密。非對稱加密算法有兩個密鑰,這兩個密鑰完全不同但又完全匹配。只有使用匹配的一對公鑰和私鑰,才能完成對明文的加密和解密過程。二 冪等性問題
冪等性是指任意多次請求的執行結果和一次請求的執行結果所產生的影響相同。說的直白一點就是查詢操作無論查詢多少次都不會影響數據本身,因此查詢操作本身就是冪等的。但是新增操作,每執行一次數據庫就會發生變化,所以它是非冪等的。冪等問題的解決有很多思路,這里講一種比較嚴謹的。提供一個生成隨機數的接口,隨機數全局唯一。調用接口的時候帶入隨機數。第一次調用,業務處理成功后,將隨機數作為key,操作結果作為value,存入redis,同時設置過期時長。第二次調用,查詢redis,如果key存在,則證明是重復提交,直接返回錯誤。三 數據規范問題
3.1 版本控制
一套成熟的API文檔,一旦發布是不允許隨意修改接口的。這時候如果想新增或者修改接口,就需要加入版本控制,版本號可以是整數類型,也可以是浮點數類型。一般接口地址都會帶上版本號,http://ip:port//v1/list。3.2 響應狀態碼規范
一個牛逼的API,還需要提供簡單明了的響應值,根據狀態碼就可以大概知道問題所在。我們采用http的狀態碼進行數據封裝,例如200表示請求成功,4xx表示客戶端錯誤,5xx表示服務器內部發生錯誤。狀態碼設計參考如下:| 1xx | 信息,服務器收到請求,需要請求者繼續執行操作 |
| 2xx | 成功 |
| 3xx | 重定向,需要進一步的操作以完成請求 |
| 4xx | 客戶端錯誤,請求包含語法錯誤或無法完成請求 |
| 5xx | 服務端錯誤 |
狀態碼枚舉類:
public?enum?CodeEnum?{????//?根據業務需求進行添加
????SUCCESS(200,"處理成功"),
????ERROR_PATH(404,"請求地址錯誤"),
????ERROR_SERVER(505,"服務器內部發生錯誤");
????
????private?int?code;
????private?String?message;
????
????CodeEnum(int?code,?String?message)?{
????????this.code?=?code;
????????this.message?=?message;
????}
????public?int?getCode()?{
????????return?code;
????}
????public?void?setCode(int?code)?{
????????this.code?=?code;
????}
????public?String?getMessage()?{
????????return?message;
????}
????public?void?setMessage(String?message)?{
????????this.message?=?message;
????}
}
3.3 統一響應數據格式
為了方便給客戶端響應,響應數據會包含三個屬性,狀態碼(code),信息描述(message),響應數據(data)。客戶端根據狀態碼及信息描述可快速知道接口,如果狀態碼返回成功,再開始處理數據。
響應結果定義及常用方法:
public?class?R?implements?Serializable?{????private?static?final?long?serialVersionUID?=?793034041048451317L;
????private?int?code;
????private?String?message;
????private?Object?data?=?null;
????public?int?getCode()?{
????????return?code;
????}
????public?void?setCode(int?code)?{
????????this.code?=?code;
????}
????public?String?getMessage()?{
????????return?message;
????}
????public?void?setMessage(String?message)?{
????????this.message?=?message;
????}
????public?Object?getData()?{
????????return?data;
????}
????/**
?????*?放入響應枚舉
?????*/
????public?R?fillCode(CodeEnum?codeEnum){
????????this.setCode(codeEnum.getCode());
????????this.setMessage(codeEnum.getMessage());
????????return?this;
????}
????/**
?????*?放入響應碼及信息
?????*/
????public?R?fillCode(int?code,?String?message){
????????this.setCode(code);
????????this.setMessage(message);
????????return?this;
????}
????/**
?????*?處理成功,放入自定義業務數據集合
?????*/
????public?R?fillData(Object?data)?{
????????this.setCode(CodeEnum.SUCCESS.getCode());
????????this.setMessage(CodeEnum.SUCCESS.getMessage());
????????this.data?=?data;
????????return?this;
????}
}
總結
本篇文章從安全性、冪等性、數據規范等方面討論了API設計規范。除此之外,一個好的API還少不了一個優秀的接口文檔。接口文檔的可讀性非常重要,雖然很多程序員都不喜歡寫文檔,而且不喜歡別人不寫文檔。為了不增加程序員的壓力,推薦使用swagger或其他接口管理工具,通過簡單配置,就可以在開發中測試接口的連通性,上線后也可以生成離線文檔用于管理API。
-?END -最近整理一份面試資料《Java技術棧學習手冊》,覆蓋了Java技術、面試題精選、Spring全家桶、Nginx、SSM、微服務、數據庫、數據結構、架構等等。獲取方式:點“?在看,關注公眾號?Java后端?并回復?777?領取,更多內容陸續奉上。推薦閱讀?1.?介紹一款 API 敏捷開發工具2.?這 4 種 ThreadLocal 你都知道嗎?3.?Windows 給力!可以扔掉 Linux 虛擬機了!4.?25 張圖搞懂「文件系統」5.?干掉煩人的 Null !
喜歡文章,點個在看? 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的symfony api 错误响应_如何设计一个牛逼的 API 接口的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux jdk安装_linux运维
- 下一篇: python listbox输入内容自动