什麼是Web API
使用HTTP協議通過網絡調用的API,是軟件組織的外部接口。通過訪問URI可以與服務器完成信息交互,獲取存放在服務器的數據信息
WEB API的重要性不斷提升,開發人員需要設計Web API的機會也越來越多,例如:
- 將已發佈的Web在線服務數據功能通過API公開
- 構建現代Web應用
- 開發智能手機應用
- 開發社交遊戲
- 公司內部多個系統的集成
那麼Web API如此重要,如何設計出優美的Web API呢?
- 易與使用
- 便於更改
- 健壯性好
- 不怕公之於衆
Web API的設計
URI的設計
方法示例:
方法名 | 說明 |
---|---|
GET | 獲取資源 |
POST | 新增資源 |
PUT | 更新已有資源 |
DELETE | 刪除資源 |
PATCH | 更新部分資源 |
HEAD | 獲取資源元信息 |
用過以用戶模塊爲例子,看下URI設計示例:
目的 | URI | 方法 |
---|---|---|
獲取用戶信息列表 | http://api.example.com/v1/users | GET |
新用戶註冊 | http://api.example.com/v1/users | POST |
獲取特定用戶信息 | http://api.example.com/v1/users/id | GET |
更新用戶信息 | http://api.example.com/v1/users/id | PUT |
刪除用戶信息 | http://api.example.com/v1/users/id | DELETE |
每個URI路徑最前面/v1
表示API版本信息,/users
和/users/id
分別表示“用戶集合”和“單個用戶”,比如ID爲1234的用戶表示爲/users/12345
接下來看下如何設計同好友關係信息的API:
目的 | URI | 方法 |
---|---|---|
獲取當前用戶好友列表 | http://api.example.com/v1/users/id/friends | GET |
添加好友 | http://api.example.com/v1/users/id/friends | POST |
刪除好友 | http://api.example.com/v1/users/id/friends/id | DELETE |
好友信息與特點用戶關聯,因此獲取好友信息可以設計爲/users/id/frineds
這樣的形式,也就是和單個用戶的URI相連,在刪除好友時,指定friends後面的ID,用好友的ID更合適,可以形成“自己的用戶ID“+“好友的用戶ID”
這種唯一形式,表示特點資源
在設計URI時需要注意:
- 使用名詞複數形式
- 注意所使用的單詞,準確簡明易懂
- 不使用空格及需要編碼的字符
- 使用連接符來連接多個單詞(- or _ or 駝峯法)
如何設計過濾操作,即需要用到查詢參數,在URI末尾?後面加一系列的參數
例如使用分頁,一般會使用limit
、offset
和per_page
、page
:
per_page=50&page=3
limit=50&offset=100
使用page和offset這類相對位置來獲取數據時,隨着數據量增加,性能會是很大的問題,因爲需要從首條數據開始計數,其次,如果數據更新頻率很高,會導致獲取當前數據出現偏差,因爲用戶獲取最開始20條數據後,準備獲取接下來的20條數據,在這段時間內數據有更新,將導致獲取數據與期望的不一致
可以使用絕對位置獲取數據,比如某個ID之前或某個日期之前等條件
用戶過濾的參數:
- http://api.example.com/v1/users?name=lwyang
- http://api.example.com/v1/users?q=lwyang
第一條可以表示名字限定爲lwyang,第二條可以表示全文搜索,檢索是否包含lwyang
使用查詢參數還是路徑?
從設計的角度,凡是可以附加在查詢參數裏的信息都可以附加在URI路徑裏,主要決策依據:
- 是否可以表示唯一資源所需信息
- 是否可以省略
資源是否唯一,如通過ID過去所需信息,該信息唯一,將ID放到路徑更合適
是否可以省略,如搜索時用到的limit、offset或page等參數,如果省略,多數情況會啓用默認值不會出錯,所以放到查詢參數更合適
響應的設計
不要做不必要的封裝,比如在返回數據結構裏,用統一結構將所有數據包裝起來
返回的JSON數據用了header和response兩個域,實際有效數據存放於response中,而header裏保存了所有API元數據,這樣的便捷性顯而易見,但封裝顯得冗長,並不值得,因爲WEB API基本都是用HTTP協議,HTTP已經完成的封裝的工作,可以通過返回合適的狀態碼來幫助用戶判斷是否發現了某種錯誤
狀態碼 | 含義 |
---|---|
1字頭 | 消息 |
2字頭 | 成功 |
3字頭 | 重定向 |
4字頭 | 客戶端錯誤 |
5字頭 | 服務端錯誤 |
當請求成功時:
GET
:成功返回200
(“OK”),返回實際數據POST
:成功返回201
(“Created”),並返回發方法所操作的數據DELETE
:成功返回204
(“No Content”)PUT、PATCH
:成功返回200
(“OK”),並返回發方法所操作的數據
當請求出錯時:
狀態碼 | 含義 |
---|---|
400 | Bad Request,其他錯誤,其他狀態碼無法描述的錯誤類型 |
401 | Unauthorized,認證錯誤,如未登陸 |
403 | Forbidden,沒有操作權限 |
404 | Not Found,訪問資源不存在 |
405 | Method Not Allowed,方法不被允許 |
406 | Not Acceptable,不支持客戶端指定數據格式 |
408 | Request Timeout,超時 |
409 | Confilct |
429 | Too Many Requests,訪問次數超出允許範圍,限速有關 |
500 | Internal Server Error,服務端自身存在問題 |
503 | Service Unavailable,服務端暫時不可用 |
當出錯時,需要返回詳細的錯誤信息,僅通過狀態碼錶示還不夠,因此可以自定義code和message,如下放在消息體中: