HTTP 和 HTTP API 设计
HTTP 基本知識
URI
URL(統一資源定位符),我們比較熟悉,URI是3個單詞的縮寫,Uniform Resource Identifier
URI用字符串表示某一互聯網資源,而URL表示資源的地點,可見URL是URI的子集;采用HTTP協議時,協議方案就是http,除此之外,還有ftp、file等,標準的URI協議有30種方案左右。
hierarchical part┌───────────────────┴──────────────────┐authority path┌───────────────┴────────────┐┌───┴────┐abc://username:password@example.com:123/path/data?key=value&key2=value2#fragid1└┬┘ └───────┬───────┘└────┬────┘└┬┘ └─────────┬───────┘ └──┬──┘ scheme user information host port query fragment 復制代碼eg:
登錄信息:指定用戶名和密碼作為從服務器端獲取資源時必要的登錄信息(身份認證),可選項。
查詢字符串:針對已指定的文件路徑內的資源,可以使用查詢字符串傳入任意參數,可選項。
片段標識符:使用片段標識符通常可標識出已獲取資源中的子資源,可選項。
URI 和 URL 的區別:
URI 用字符串標識某一互聯網資源,而 URL 標識資源的地址
URL 是 URI 的子集
基本規定
-
發送規則
HTTP協議規定,請求從客戶端發出,最后服務器端響應該請求并返回
-
HTTP無狀態
HTTP是一種不保存狀態,即無狀態協議,不會對之前發送過的請求進行信息的保存
常用HTTP方法
-
GET(SELECT):從服務器取出資源(一項或多項)
-
POST(CREATE):在服務器新建一個資源
-
PUT(UPDATE):在服務器更新資源(客戶端提供改變后的完整資源)
-
PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性)(一般使用PUT)
-
DELETE(DELETE):從服務器刪除資源
Cookie 狀態管理
cookie會根據服務端發送的一個叫做Set-Cookie的首部字段信息,通知客服端保存Cookie,當下次客服端在往服務端發送請求的時候,客服端會自動在請求報文中加入Cookie然后發送過去,服務端接收到Cookie之后,對Cookie進行解析,然后找出是哪個用戶。
eg:
一、請求報文(沒有Cookie信息的狀態)
GET /reader/HTTP/1.1 Host:host // 首部字段沒有cookie的相關信息 復制代碼二、響應報文(服務器端生成Cookie信息)
HTTP/1.1 200 OK Date:Thu ,12 JUl 2012 07:12:20 GMT Server: Apache <Set-Cookie:sid=1342077140;path=/;expires=wed> Content-Type:text/plain;charset=UTF-8 復制代碼三、請求報文(自動發送保存的Cookie信息)
GET /image/ HTTP/1.1 Host host Cookie:sid=1342077140 復制代碼HTTP報文
結構:首部 + 主體
首部
分類:通用首部、請求首部、響應首部、實體首部、拓展首部
-
通用首部:客戶端和服務端都可以用,描述一些通用信息
-
請求首部:請求報文特有,為服務器提供額外信息
-
響應首部:響應報文特有,為客戶端提供信息
-
實體首部:描述實體主體部分的首部
-
拓展首部:非標準首部,由應用開發者創建,未添加到HTTP規范中
通用首部
-
Date:報文創建時間
-
Connection:客戶端和服務器連接的有關選項
-
Via:報文經過的中間節點(代理、網關)
-
Cache-control:緩存
請求首部
-
Host:接受請求的服務器的主機名和端口
-
Referer:當前請求的URL
-
UA-OS:客戶端操作系統及版本
-
Accept:告訴服務器能夠發送的媒體類型
-
Accept-Charset:告訴服務器能夠發送的字符集
-
Accept-Encoding:告訴服務器能夠發送的編碼方式
-
Accept-Language:告訴服務器能夠發送的語言
-
Authorization:包含客戶端提供給服務端,以便進行安全認證的數據
-
Cookie:客戶端需要發送的cookie
-
Cache-Control: 取值為一般為no-cache或max-age=XX,XX為個整數,表示該資源緩存有效期(秒)
實體首部
-
Allow:對該實體可執行的請求方法
-
Location:資源的新地址,重定向中常用到
-
Content-Language:理解主體應該使用的語言
-
Content-Length:主體的長度
-
Content-Encoding:對主體實行的編碼方式
-
Content-Type:主體的類型
-
Expires:實體不再有效,需要再次獲取該實體的時間
-
Last-Modified:實體最后一次被修改的時間
響應首部
-
Server:服務器應用軟件名稱及版本
-
Set-Cookie:設置cookie
HTTP 狀態碼
MDN http status code
MDN http status code -zh-CN
-
1xx 信息響應
-
2xx 成功相應
-
3xx 重定向
-
4xx 客戶端響應
-
5xx 服務端響應
HTTP API 設計指南
使用 HTTPS
版本化
-
在 URL 中標明版本
eg:
http://shonzilla/api/v2.2/customers/1234 http://shonzilla/api/v2.0/customers/1234 http://shonzilla/api/v2/customers/1234 http://shonzilla/api/v1.1/customers/1234 http://shonzilla/api/v1/customers/1234 復制代碼 -
在 Header 中標明版本
-
-
自定義 header
HTTP GET: https://haveibeenpwned.com/api/breachedaccount/foo api-version: 2 復制代碼
-
-
-
利用 content type
HTTP GET: https://haveibeenpwned.com/api/breachedaccount/foo Accept: application/vnd.haveibeenpwned.v2+json 復制代碼HTTP GET: https://haveibeenpwned.com/api/breachedaccount/foo Accept: application/vnd.haveibeenpwned+json; version=2.0 復制代碼
-
返回合適的狀態碼
為每一次的響應返回合適的HTTP狀態碼. 成功的HTTP響應應該使用如下的狀態碼:
-
200: GET請求成功, 以及DELETE或 PATCH 同步請求完成
-
201: POST 同步請求完成
-
202: POST, DELETE, 或 PATCH 異步請求將要完成
-
。。。
對于用戶請求的錯誤情況,及服務器的異常錯誤情況,請查閱完整的HTTP狀態碼 HTTP response code spec
在請求的body體使用JSON數據
在 PUT/PATCH/POST 請求的body體使用JSON格式數據, 而不是使用 form 表單形式的數據. 這里我們使用JSON格式的body請求創建對稱的格式數據, 例如.:
$ curl -X POST https://service.com/apps \-H "Content-Type: application/json" \-d '{"name": "demoapp"}'{"id": "01234567-89ab-cdef-0123-456789abcdef","name": "demoapp","owner": {"email": "username@example.com","id": "01234567-89ab-cdef-0123-456789abcdef"},... } 復制代碼提供資源的唯一標識
在默認情況給每一個資源一個id屬性. 用此作為唯一標識除非你有更好的理由不用.不要使用那種在服務器上或是資源中不是全局唯一的標識,比如自動增長的id標識。
返回的唯一標識要用小寫字母并加個分割線格式 8-4-4-4-12, 例如.:
"id": "01234567-89ab-cdef-0123-456789abcdef" 復制代碼提供標準的時間戳
提供默認的資源創建時間,更新時間 created_at and updated_at , 例如:
{..."created_at": "2012-01-01T12:00:00Z","updated_at": "2012-01-01T13:00:00Z",... } 復制代碼這些時間戳可能不適用于某些資源,這種情況下可以忽略省去。
使用ISO8601的國際化時間格式
在接收的返回時間數據時只使用UTC格式. 查閱ISO8601時間格式, 例如:
"finished_at": "2012-01-01T12:00:00Z" 復制代碼使用統一的資源路徑
資源命名
使用復數形式為資源命名
形為
好的末尾展現形式不許要指定特殊的資源形為,在某些情況下,指定特殊的資源的形為是必須的,用一個標準的actions前綴去替代他, 清楚的描述他:
/resources/:resource/actions/:action 復制代碼例如.
/runs/{run_id}/actions/stop 復制代碼路徑和屬性要用小寫字母
使用小寫字母并用-短線分割路徑名字,并且緊跟著主機域名 e.g:
service-api.com/users service-api.com/app-setups 復制代碼同樣屬性也要用小寫字母, 但是屬性名字要用下劃線_分割。例如.:
"service_class": "first" 復制代碼嵌套外鍵關系
序列化的外鍵關系通常建立在一個有嵌套關系的對象之上, 例如.:
{"name": "service-production","owner": {"id": "5d8201b0..."},... } 復制代碼而不是這樣 例如:
{"name": "service-production","owner_id": "5d8201b0...",... } 復制代碼這種方式盡可能的把相關聯的資源信息內聯在一起,而不用改變響應資源的結構,或者展示更高一級的響應區域, 例如:
{"name": "service-production","owner": {"id": "5d8201b0...","name": "Alice","email": "alice@heroku.com"},... } 復制代碼支持方便的無id間接引用
在某些情況下,為了方便用戶使用接口,在末尾提供用id標識資源,例如,一個用戶想到了他在heroku平臺app的名字,但是這個app的唯一標識是id,這種情況下,你想讓接口通過名字和id都能訪問,例如:
$ curl https://service.com/apps/{app_id_or_name} $ curl https://service.com/apps/97addcf0-c182 $ curl https://service.com/apps/www-prod 復制代碼不要只接受使用名字而剔除了使用id。
構建錯誤信息
在網絡請求響應錯誤的時候,返回統一的,結構化的錯誤信息。要包含一個機器可讀的錯誤 id,一個人類能識別的錯誤信息 message, 根據情況可以添加一個url ,告訴客戶端關于這個錯誤的更多信息以及如何去解決它。 例如:
HTTP/1.1 429 Too Many Requests 復制代碼{"id": "rate_limit","message": "Account reached its API rate limit.","url": "https://docs.service.com/rate-limits" } 復制代碼把你的錯誤信息格式文檔化,以及這些可能的錯誤信息ids 讓客戶端能獲取到.
用id來跟蹤每次的請求
在每一個API響應中要包含一個Request-Id頭信息, 通常用唯一標識UUID. 如果服務器和客戶端都打印出他們的Request-Id, 這對我們的網絡請求調試和跟蹤非常有幫助.
按范圍分頁
對于服務器響應的大量數據我們應該為此分頁。 使用Content-Range 頭傳遞分頁請求的數據.這里有個例子詳細的說明了請求和響應頭、狀態碼,限制條件、排序以及分頁處理:Heroku Platform API on Ranges.
注:服務器會在響應頭中添加 Accept-Ranges: bytes 來表示支持 Range 的請求,之后客戶端才可能發起帶 Range 的請求
eg:
# first Content-Length:1200 Content-Range:bytes 0-1199/5000# second Content-Length:1200 Content-Range:bytes 1200-2399/5000# third Content-Length:1200 Content-Range:bytes 2400-3599/5000# fourth Content-Length:1400 Content-Range:bytes 3600-5000/5000 復制代碼顯示速度限制狀態
客戶端的訪問速度限制可以維護服務器的良好狀態,進而為其他客戶端請求提供高性的服務
為每一個帶有 RateLimit-Remaining 響應頭的請求,返回預留的請求tokens。
指定可接受頭信息的版本
在開始的時候指定API版本,使用Accepts頭傳遞版本信息,也可以是一個自定義的內容, 例如:
Accept: application/vnd.heroku+json; version=3 復制代碼最好不要給出一個默認的版本, 而是要求客戶端明確指明他們要使用特定的版本.
提供人類可讀的文檔
提供人類可讀的文檔讓客戶端開發人員可以理解你的API。
除此之在詳細信息的結尾,提供一個關于如下信息的API摘要:
-
驗證授權,包含獲取及使用驗證tokens.
-
API 穩定性及版本控制, 包含如何選擇所需要的版本.
-
一般的請求和響應頭信息.
-
錯誤信息序列格式.
-
不同語言客戶端使用API的例子.
提供可執行的示例
提供可執行的示例讓用戶可以直接在終端里面看到API的調用情況,最大程度的讓這些示例可以逐字的使用,以減少用戶嘗試使用API的工作量。例如:
$ export TOKEN=... # acquire from dashboard $ curl -is https://$TOKEN@service.com/users 復制代碼轉載于:https://juejin.im/post/5cfa1f2751882575f333f614
《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀總結
以上是生活随笔為你收集整理的HTTP 和 HTTP API 设计的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LeetCode每日一题:N叉树的层序遍
- 下一篇: Java序列化,看这篇就够了!