摘要:此文已由作者鄭華斌授權網易云社區發布。結合最近的項目,總結下常見的違背設計的一些做法。其實有個原則叫統一接口,統一接口原則建議了各方法的使用場合,獲取資源,返回消息頭和消息表示,即和。參考文獻文章來源網易云社區
此文已由作者鄭華斌授權網易云社區發布。
REST這詞我們常常掛在嘴邊,比如“開發一個rest接口”,又比如Spring項目的代碼:
@RestControllerpublic class CommonController { @RequestMapping("/") public String index() { return "Welcome to Yanxuan DMS!";
}
CommonController使用了@RestController注解,顧名思義,告訴讀者這是一個Rest接口的實現。然而以@RestController注解的接口卻不一定符合Rest原則。結合最近的項目,總結下常見的違背Rest設計的一些做法。
一、一律使用POST或者GET方法
典型的錯誤做法:無論什么請求,一律用POST,或者‘增刪改’用POST,‘查’用GET。
其實REST有個原則叫統一接口(uniform interface),統一接口原則建議了各http方法的使用場合,
GET:獲取資源,返回消息頭和消息表示,即header和body。
HEAD:獲取資源元數據,返回消息頭
DELETE:刪除資源
POST:REST設計中,POST通常用來為一個已有資源創建一個從屬資源(subordinate resource),如AWS S3的POST Object(或者稱web post)接口。
PUT:創建或修改一個資源
PUT和POST的區別比較微妙,這里拿AWS S3(或者參考網易對象存儲NOS)的接口設計來舉例。其中AWS S3的詳細API文檔參見:http://docs.aws.amazon.com/Am...。 S3有兩種資源,桶(bucket)和對象(object),對象從屬于某個桶。
創建一個桶的接口為:
PUT /BucketName HTTP/1.1
Host: s3.amazonaws.com
創建/修改一個對象的PUT Object接口為:
PUT /BucketName/ObjectName HTTP/1.1
Host: s3.amazonaws.com[對象數據]
AWS S3同時提供了POST Object接口,同樣可以創建/修改一個對象,如下
POST /BucketName HTTP/1.1Host: s3.amazonaws.comContent-Type: multipart/form-data; boundary=9431149156168[包含對象數據的body]
獲取對象的GET Object接口為:
GET /BucketName/ObjectName HTTP/1.1
Host: s3.amazonaws.com
同樣的創建/修改一個對象,一個用PUT方法,另一個用POST方法,為什么?關鍵在于URL,PUT請求的目標URL(這里為/BucketName/ObjectName),就是將來用于獲取該對象的URL,即PUT Object和GET Object的URL是一致的。但是POST Object的URL與GET ObjectURL不一樣,POST 請求只知道父資源的URL(即/BucketName),表示在該父資源下創建新資源,至于新資源的確切URL,是由服務器決定的,一般來說是POST請求的響應應該包含一個Location消息頭,其包含新建從屬資源的URL。
安全性safe和冪等性idempotent
REST設計還應該遵循安全性和冪等性約束,如下:
GET和HEAD應當是安全的:GET和HEAD請求不應該導致服務器狀態發生改變
GET、HEAD、PUT和DELETE應當是冪等的:向一個URL發送多次PUT和DELETE請求,跟只做過一次請求一樣。比如PUT不能是append語義,否則不冪等。GET和HEAD也是冪等。
統一接口原則的好處:
給一個資源URI,不用看文檔就知道可以有GET、DELETE等操作及其意義,世界通用。
安全性和冪等性增加了http的可靠性:如果請求沒成功(但也許已成功了),只需重新發一次即可,不用擔心副作用。
二、HTTP Code一律返回200
典型的錯誤做法:無論成功失敗,HTTP Code一律返回200,具體錯誤信息交由json body里的內容來判斷,舉例如下,
某甲服務xxx接口的響應如下
HTTP/1.1 200 OK{ "status":1, //1: 成功 0: 參數異常 -1: 失敗
"message":"" //返回的消息 成功時返回的數據
}
某乙服務xxx接口的響應如下
HTTP/1.1 200 OK{ "code":200, //1: 成功 0: 參數異常 -1: 失敗
"msg":"" //code非200時返回的錯誤信息 "data":{成功時返回的數據內容}
}
其實RESTful的設計的一個標志特征是充分并正確利用HTTP響應碼,典型的如:
200 -- OK,成功
301 -- Moved Permanently,重定向
400 -- Bad Request,錯誤的請求,比如缺少參數或者參數值不對
403 -- Forbidden,無權限訪問
404 -- Not Found,url不存在
500 -- Internal Server Error,系統錯誤,如數據庫訪問失敗或者bug導致的錯誤
設計REST接口應該遵循上面的響應碼,語義明確并通用。如果像上面例子那樣,任何情況都一律返回200,而具體成功與否需要到http響應消息體里去解析,而且不同的服務或開發者自定義消息體的格式,那么服務調用方就需要針對不同的服務寫不同的判斷邏輯,增加系統交互復雜性。
有些通用的客戶端,會針對301自動處理重定向,針對500以上的響應自動重試,而一律返回200的設計是沒法使用這些特性的,只能調用方一一自個處理。
三、 面向操作而不是面向資源的url設計
典型的錯誤做法:設計的URI是面向操作而不是面向資源的,舉例如下,
某系統 設計的渠道相關的URI是這樣的:
新增渠道
POST /xhr/thirdparty/admin/channel/add.json?{渠道信息參數}
編輯渠道
POST /xhr/thirdparty/admin/channel/update.json?{渠道信息參數}
刪除渠道
POST /xhr/thirdparty/admin/channel/delete.json?channelId=id
這里的接口設計有三個特點:
http方法都是POST;
URI里攜帶操作信息,如URI里出現“add”,“update”,“delete”等字眼;
同一個資源由于操作不一樣而URI不一樣。
其實REST式的設計中,URI即是資源的名稱,也是資源的地址,因為不同的操作而資源地址不一樣是不合適的。資源的操作(方法信息)應該由統一接口來表示,即http 方法PUT、POST、GET、DELETE等,而不應該放到URI中。
對照統一接口和面向資源這兩個特征來設計,上面的接口RESTful化可以是這樣的:
新增渠道
POST /xhr/thirdparty/admin/channel
[渠道具體信息]
修改渠道
PUT /xhr/thirdparty/admin/channel?channelId=id 或者PUT /xhr/thirdparty/admin/channel/${id}
[渠道具體信息]
刪除渠道
DELETE /xhr/thirdparty/admin/channel?channelId=id或者DELETE /xhr/thirdparty/admin/channel/${id}
渠道的地址為/xhr/thirdparty/admin/channel?channelId=id或者/xhr/thirdparty/admin/channel/${id},重在url唯一。
參考文獻
《RESTful Web Services》
文章來源: 網易云社區
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/25333.html
摘要:前言關于設計模式,想必大家的第一感覺就是過于高深,有點虛吧。為什么要學習設計模式因為要裝逼啊咳咳,大家請忽略前面那句話。處處都是設計模式的體現,所以若想攻下,設計模式是必學的。下節預告單例模式 前言 關于設計模式,想必大家的第一感覺就是過于高深,有點虛吧。相對來說,我們還是更熟悉ssh或者ssm之類的開發框架,一個工具用久了就會熟能生巧,就像刷漆工,時間長了也知道如何刷的一手漂亮的好墻...
摘要:飛機就是一種交通工具,可飛行的能力是是飛機的屬性,通過繼承接口來獲取語言可沒有接口功能,但是它可以多重繼承。說是,因為從語法上看,的確是通過多重繼承實現的。所以從含義上理解,只是一個,不是一個。比如飛機照樣可以載客,就是不能飛了 REST API設計理念 showImg(https://segmentfault.com/img/remote/1460000019923606);sho...
摘要:飛機就是一種交通工具,可飛行的能力是是飛機的屬性,通過繼承接口來獲取語言可沒有接口功能,但是它可以多重繼承。說是,因為從語法上看,的確是通過多重繼承實現的。所以從含義上理解,只是一個,不是一個。比如飛機照樣可以載客,就是不能飛了 REST API設計理念 showImg(https://segmentfault.com/img/remote/1460000019923606);sho...
摘要:策略模式又稱政策模式,其定義一系列的算法,把它們一個個封裝起來,并且使它們可以互相替換。的表單具有表單驗證功能,用來校驗用戶輸入的表單內容。實際需求中表單驗證項一般會比較復雜,所以需要給每個表單項增加自定義校驗方法。 showImg(https://segmentfault.com/img/remote/1460000020135990); 策略模式 (Strategy Pattern...
摘要:如何快速搭建一個微服務架構上圖異步通信方式通常異步的生產者消費者模式,通過等異步消息通訊協議規范。數據的去中心化,進一步降低了微服務之間的耦合度,不同服務可以采用不同的數據庫技術等。 什么是微服務? 微服務(Microservices Architecture)是一種架構風格,一個大型復雜軟件應用由一個或多個微服務組成。系統中的各個微服務可被獨立部署,各個微服務之間是松耦合的。每個微服...
閱讀 1470·2019-08-30 15:55
閱讀 1172·2019-08-30 15:52
閱讀 1282·2019-08-29 13:53
閱讀 1465·2019-08-29 11:19
閱讀 2964·2019-08-26 13:29
閱讀 527·2019-08-26 11:33
閱讀 2587·2019-08-23 17:20
閱讀 1022·2019-08-23 14:14