摘要:為了避免的變動導致用戶使用中產生意外結果或調用失敗,最好強制要求所有訪問都需要指定版本號。請避免提供默認版本號,一旦提供,日后想要修改它會相當困難。返回結果針對不同操作,服務器向用戶返回的結果應該符合以下規范。
API的定義取決于選擇的IPC通信方式,如果是消息機制(如 AMQP 或者 STOMP),API則由消息頻道(channel)和消息類型;如果是使用HTTP機制,則是基于請求/響應(調用http的url),這里我們先簡述下RestfulAPI的定義。
設計原則 域名應該盡量將API部署在專用域名之下,如:
https://api.example.com
也可以放在主域名下:
https://example.org/api/版本
放入到頭信息的Accept中
制定版本并在版本之間平緩過渡對于設計和維護一套API是個巨大的挑戰。所以,最好在設計之初就使用一些方法來預防可能會遇到的問題。
為了避免API的變動導致用戶使用中產生意外結果或調用失敗,最好強制要求所有訪問都需要指定版本號。請避免提供默認版本號,一旦提供,日后想要修改它會相當困難。
最適合放置版本號的位置URL中,或者是頭信息(HTTP Headers)中在 Accept 段中使用自定義類型(content type)與其他元數據(metadata)一起提交。
https://api.example.com/v1/ 或 Accept: application/vnd.heroku+json; version=3提供 Request-Id
為每一個請求響應包含一個Request-Id字段,并使用UUID作為該值。通過在客戶端、服務器或任何支持服務上記錄該值,它能主我們提供一種機制來跟蹤、診斷和調試請求。
路徑 資源名在RESTful架構中,每個網址代表一種資源(resource),所以網址中不能有動詞,只能有名詞,而且所用的名詞往往與數據庫的表格名對應。一般來說,數據庫中的表都是同種記錄的”集合”(collection),所以API中的名詞也應該使用復數。
舉例來說,有一個API提供動物園(zoo)的信息,還包括各種動物和雇員的信息,則它的路徑應該設計成下面這樣。
https://api.example.com/v1/zoos https://api.example.com/v1/animals https://api.example.com/v1/employees行為(Actions)
好的末尾不需要為資源指定特殊的行為,但在特殊情況下,為某些資源指定行為卻是必要的。為了描述清楚,在行為前加上一個標準的actions:
/resources/:resource/actions/:action
如:
/runs/{run_id}/actions/stop路徑和屬性名
為了和域名命名規則保持一致,使用小寫字母并用-分割路徑名字,例如:
service-api.com/users service-api.com/app-setups
屬性也使用小寫字母,但是屬性名要用下劃線_分割,以便在Javascript中省略引號。 例如:
service_class: "first"支持方便的無id間接引用
在某些情況下,讓用戶提供ID去定位資源是不方便的。例如,一個用戶想取得他在Heroku平臺app信息,但是這個app的唯一標識是UUID。這種情況下,你應該支持接口通過名字和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。
最小化路徑嵌套在一些有父路徑/子路徑嵌套關系的資源數據模塊中,路徑可能有非常深的嵌套關系,例如:
/orgs/{org_id}/apps/{app_id}/dynos/{dyno_id}
推薦在根(root)路徑下指定資源來限制路徑的嵌套深度。使用嵌套指定范圍的資源。在上述例子中,dyno屬于app,app屬于org可以表示為:
/orgs/{org_id} /orgs/{org_id}/apps /apps/{app_id} /apps/{app_id}/dynos /dynos/{dyno_id}HTTP動詞
對于資源的具體操作類型,由HTTP動詞表示。
常用的HTTP動詞有下面五個(括號里是對應的SQL命令):
GET(SELECT):從服務器取出資源(一項或多項)。 POST(CREATE):在服務器新建一個資源。 PUT(UPDATE):在服務器更新資源(客戶端提供改變后的完整資源)。 PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性)。 DELETE(DELETE):從服務器刪除資源。
一些例子:
GET /zoos:列出所有動物園 POST /zoos:新建一個動物園 GET /zoos/ID:獲取某個指定動物園的信息 PUT /zoos/ID:更新某個指定動物園的信息(提供該動物園的全部信息) PATCH /zoos/ID:更新某個指定動物園的信息(提供該動物園的部分信息) DELETE /zoos/ID:刪除某個動物園 GET /zoos/ID/animals:列出某個指定動物園的所有動物 DELETE /zoos/ID/animals/ID:刪除某個指定動物園的指定動物過濾信息
如果記錄數量很多,服務器不可能都將它們返回給用戶。API應該提供參數,過濾返回結果。
下面是一些常見的參數:
?limit=10:指定返回記錄的數量 ?offset=10:指定返回記錄的開始位置。 ?page=2&per_page=100:指定第幾頁,以及每頁的記錄數。 ?sortby=name&order=asc:指定返回結果按照哪個屬性排序,以及排序順序。 ?animal_type_id=1:指定篩選條件
參數的設計允許存在冗余,即允許API路徑和URL參數偶爾有重復。比如,GET /zoo/ID/animals 與 GET /animals?zoo_id=ID 的含義是相同的。
響應(Responses) 狀態碼服務器向用戶返回的狀態碼和提示信息,常見的有以下一些(方括號中是該狀態碼對應的HTTP動詞):
200 OK - [GET]:服務器成功返回用戶請求的數據,該操作是冪等的(Idempotent)。 201 CREATED - [POST/PUT/PATCH]:用戶新建或修改數據成功。 202 Accepted - [*]:表示一個請求已經進入后臺排隊(異步任務) 204 NO CONTENT - [DELETE]:用戶刪除數據成功。 400 INVALID REQUEST - [POST/PUT/PATCH]:用戶發出的請求有錯誤,服務器沒有進行新建或修改數據的操作,該操作是冪等的。 401 Unauthorized - [*]:表示用戶沒有權限(令牌、用戶名、密碼錯誤)。 403 Forbidden - [*] 表示用戶得到授權(與401錯誤相對),但是訪問是被禁止的。 404 NOT FOUND - [*]:用戶發出的請求針對的是不存在的記錄,服務器沒有進行操作,該操作是冪等的。 406 Not Acceptable - [GET]:用戶請求的格式不可得(比如用戶請求JSON格式,但是只有XML格式)。 410 Gone -[GET]:用戶請求的資源被永久刪除,且不會再得到的。 422 Unprocesable entity - [POST/PUT/PATCH] 當創建一個對象時,發生一個驗證錯誤。 500 INTERNAL SERVER ERROR - [*]:服務器發生錯誤,用戶將無法判斷發出的請求是否成功。提供資源的(UU)ID
在默認情況給每一個資源一個id屬性。除非有更好的理由,否則請使用UUID。不要使用那種在服務器上或是資源中不是全局唯一的標識,尤其是自動增長的id。
生成小寫的UUID格式 8-4-4-4-12,例如:
"id": "01234567-89ab-cdef-0123-456789abcdef"提供標準的時間戳
為資源提供默認的創建時間 created_at 和更新時間 updated_at,例如:
{ ... "created_at": "2012-01-01T12:00:00Z", "updated_at": "2012-01-01T13:00:00Z", ... }使用UTC(世界標準時間)時間,用ISO8601進行格式化
在接收和返回時都只使用UTC格式(ISO8601格式的數據)或者使用時間戳。,例如:
"finished_at": "2012-01-01T12:00:00Z"
或
"timestamp": "1472486035"錯誤處理
如果狀態碼是4xx,就應該向用戶返回出錯信息。一般來說,返回的信息中將error作為鍵名,出錯信息作為鍵值即可。
{ error: "Invalid API key" }返回結果
針對不同操作,服務器向用戶返回的結果應該符合以下規范。
GET /collection:返回資源對象的列表(數組) GET /collection/resource:返回單個資源對象 POST /collection:返回新生成的資源對象 PUT /collection/resource:返回完整的資源對象 PATCH /collection/resource:返回完整的資源對象 DELETE /collection/resource:返回一個空文檔保證響應JSON及最小化
目前為保證響應最小化,一般使用json字符串,并且請求中多余的空格會增加響應大小,而且現在很多的HTTP客戶端都會自己輸出可讀格式("prettify")的JSON。所以最好保證響應JSON最小化,例如:
{"beta":false,"email":"alice@heroku.com","id":"01234567-89ab-cdef-0123-456789abcdef","last_login":"2012-01-01T12:00:00Z","created_at":"2012-01-01T12:00:00Z","updated_at":"2012-01-01T12:00:00Z"}
而不是這樣:
{ "beta": false, "email": "alice@heroku.com", "id": "01234567-89ab-cdef-0123-456789abcdef", "last_login": "2012-01-01T12:00:00Z", "created_at": "2012-01-01T12:00:00Z", "updated_at": "2012-01-01T12:00:00Z" }Hypermedia API
RESTful API最好做到Hypermedia,即返回結果中提供鏈接,連向其他API方法,使得用戶不查文檔,也知道下一步應該做什么。
比如,當用戶向api.example.com的根目錄發出請求,會得到這樣一個文檔。
{"link": { "rel": "collection https://www.example.com/zoos", "href": "https://api.example.com/zoos", "title": "List of zoos", "type": "application/vnd.yourformat+json" }}
上面代碼表示,文檔中有一個link屬性,用戶讀取這個屬性就知道下一步該調用什么API了。rel表示這個API與當前網址的關系(collection關系,并給出該collection的網址),href表示API的路徑,title表示API的標題,type表示返回類型。
Hypermedia API的設計被稱為HATEOAS。Github的API就是這種設計,訪問api.github.com會得到一個所有可用API的網址列表。
{ "current_user_url": "https://api.github.com/user", "authorizations_url": "https://api.github.com/authorizations", // ... }
從上面可以看到,如果想獲取當前用戶的信息,應該去訪問api.github.com/user,然后就得到了下面結果。
{ "message": "Requires authentication", "documentation_url": "https://developer.github.com/v3" }
上面代碼表示,服務器給出了提示信息,以及文檔的網址。
參考文章github的restful接口
Restful API淺析 之設計原則與案例修正
http-api-design
by 劉迎光@螢火蟲工作室
OpenBI交流群:495266201
MicroService 微服務交流群:217722918
mail: liuyg#liuyingguang.cn
博主首頁(==防止爬蟲==):http://blog.liuyingguang.cn
OpenBI問答社區:http://www.openbi.tk
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/26807.html
摘要:微服務架構模式使得每個微服務獨立部署,且每個服務獨立擴展,開發者不再需要協調其它服務部署對本服務的影響。微服務架構模式使得持續化部署成為可能。所以使用微服務不是必須的,而是在適當的實際,架構適應應用場景的一種改變。 近段時間離職,跟同事們講解我之前所做的微服務相關產品,對于同事們提出的問題,做了如下整理出來,加上自己的理解,分享出來跟大家一起探討下: 問題預覽 我為什么要換微服務?能...
摘要:每個微服務提供一組,供其他微服務或者應用客戶端所用。由于微服務架構的分布式特點,測試一個基于微服務架構的應用也是很復雜的任務。微服務架構模式下,應用的改變將會波及多個服務。 微服務Microservices已經成為軟件架構最流行的熱詞之一。網絡上看到很多關于微服務的文章,但是感覺很多離我們還很遙遠,并且沒有找到多少真正在企業場景中應用的實例。此處省略一萬字~~~~于是想要將自己最近一段...
摘要:微服務常用的進程間通信技術即表述性狀態傳遞英文,簡稱是博士在年他的博士論文中提出來的一種軟件架構風格。摘自微服務實戰從架構到部署處理部分請求失敗對于分布式的微服務,必須要面對的一大問題就是局部請求失敗的處理。 先拋出幾個問題 微服務架構的交互模式有哪些? 微服務常用的進程間通信技術有哪些? 如何處理部分請求失敗? API的定義需要注意的事項有哪些 微服務的通信機制與SOA的通信機制之...
閱讀 2907·2021-11-19 09:40
閱讀 3578·2021-10-09 09:43
閱讀 2675·2021-09-22 15:31
閱讀 1724·2021-07-30 15:31
閱讀 782·2019-08-30 15:55
閱讀 3256·2019-08-30 15:54
閱讀 1160·2019-08-30 11:26
閱讀 1907·2019-08-29 13:00