細說Restful API之冪等性

接口冪等性的含義

冪等性原本是數(shù)學中的含義稚矿,表達的是N次變換與1次變換的結(jié)果相同捻浦。

而RESTFul API中的冪等性是指調(diào)用某個接口1次或N次桥爽,對所訪問的資源產(chǎn)生的影響結(jié)果都是相同的钠四,需要特別注意的是:這里冪等性指的是對資源產(chǎn)生的影響結(jié)果,而非調(diào)用HTTP請求的返回結(jié)果缀去。

舉個例子,RESTFul API中的GET方法是查詢資源信息褥影,不會對資源產(chǎn)生影響咏雌,所以它是符合冪等性的,但是每次調(diào)用GET方法返回的結(jié)果有可能不同(可能資源的某個屬性在調(diào)用GET方法之前已經(jīng)被其他方法修改了赊抖,例如在多次訪問期間氛雪,接口返回對象的update_time字段被別的請求更新,但GET本身是冪等性的)坛缕。

實際上捆昏,在分布式架構(gòu)中的API冪等性不僅僅針對RESTFul接口毙沾,而是對所有類型的接口適用,目的是為了確保調(diào)用1次或N次接口時對資源的影響結(jié)果都是相同的寇仓。

接口冪等性的好處

接口的冪等性確保了無論調(diào)用1次還是N次對資源的影響都是相同的遍烦,這在某些場合下是非常有用的躺枕。

舉個業(yè)務場景:用戶下單供填,銀行從用戶賬戶扣款罢猪。

有這樣一個接口方法:pay(long account, int money),該方法用于銀行卡扣款支付粘捎,參數(shù)account為賬戶ID危彩,money為需要扣除的錢數(shù)。

當用戶從網(wǎng)頁上點擊支付按鈕時娩缰,在該方法的實現(xiàn)邏輯中需要從指定賬戶中扣除對應的商品價錢泻骤。如果支付操作已經(jīng)成功執(zhí)行,但是響應消息因為某種原因未能及時返回給客戶端演痒,這時候給用戶的體驗是可能是未支付成功趋惨,如果此時再次點擊支付按鈕,那么將再一次執(zhí)行該方法讯嫂,結(jié)果可能會導致用戶只買了一件商品卻扣減了雙份的錢兆沙,這當然是不合理的。整個流程如下圖所示:

當然千扔,就上述例子的場景曲楚,為了避免用戶重復支付褥符,是可以通過別的方式解決的,比如:分布式事務趟大;或者根據(jù)支付狀態(tài)提示給予用戶進行提示等等。

但是护昧,如果引入了分布式事務,那么將帶來實現(xiàn)上的復雜性捣炬,而且會影響到接口性能绽榛;而采取提示信息的方式并不能百分之百確保用戶不會重復支付,存在一定的風險灭美。

而如果接口符合冪等性,即:對同一個訂單無論是執(zhí)行一次支付還是多次支付铁坎,在服務端都確保只會扣一次款犁苏,那么既不需要引入分布式事務的復雜性,也能從根本上解決重復支付的問題围详,這也就是接口符合冪等性的價值所在助赞。

總而言之,接口符合冪等性在可以降低系統(tǒng)實現(xiàn)的復雜性畜普,并能保證資源狀態(tài)的一致性群叶。

HTTP方法的冪等性與安全性

RESTFul風格的接口設(shè)計本質(zhì)上使用的是HTTP協(xié)議的請求方法,因此,RESTFul接口方法的冪等性指的就是HTTP方法的冪等性几晤。

常用的HTTP方法有:

  • OPTIONS(獲取服務器信息)
  • HEAD(請求資源首部信息)
  • GET(獲取資源)
  • POST(創(chuàng)建資源)
  • PUT(更新資源全部信息)
  • PATCH(更新資源部分信息)
  • DELETE(刪除資源)

那么植阴,這些HTTP方法的冪等性又是什么樣的呢圾浅?除了冪等性之外狸捕,HTTP方法的安全性是指不對資源產(chǎn)生修改众雷。
如下是常用HTTP方法的冪等性和安全性總結(jié):

HTTP方法名稱 是否冪等 是否安全
OPTIONS Y Y
HEAD Y Y
GET Y Y
POST N N
PUT Y N
PATCH N N
DELETE Y N

從上述表格中可以看出砾省,HTTP方法的冪等性和安全性并不是同一個概念,如下是對個各個方法的冪等性和安全性解釋:

  • OPTIONS方法常常用于獲取服務器信息轩性,不會對資源產(chǎn)生影響狠鸳,也不會對資源進行修改件舵,因此它是冪等的也是安全的;OPTIONS方法最常見的場景是在瀏覽器的跨域請求中蛾派,如果瀏覽器發(fā)起的是一個跨域訪問的API(不論是GET方法還是POST方法)个少,再真正發(fā)送業(yè)務的GET或POST方法之前會發(fā)送一個OPTIONS方法從服務端獲取信息,從服務器返回的信息中得知該請求是否支持跨域訪問壳澳,從而決定下一步是否能成功發(fā)送真正的業(yè)務請求茫经。
  • HEAD方法用于請求資源的頭部信息,不會資源產(chǎn)生影響抹镊,也不會對資源進行修改荤傲,因此它是冪等的也是安全的垮耳。
  • GET方法用于獲取資源信息,雖然可能每次返回的結(jié)果都不相同,但是GET方法本身不會對資源產(chǎn)生影響终佛,在RESTFul語義里GET方法也不會修改資源俊嗽,因此它是冪等的,也是安全的铃彰。
  • POST方法在RESTFul語義里表示新建資源绍豁,顯然調(diào)用1次與調(diào)用N次的結(jié)果不同(調(diào)用1次新建1個資源,調(diào)用N次新建N個資源)牙捉,因此不是冪等的竹揍,同時也不是安全的。
  • PUT方法在RESTFul語義里表示對資源進行全量更新鹃共,因此調(diào)用1次或N次的結(jié)果都是一致的鬼佣,所以它是冪等的,但不是安全的霜浴。
  • PATCH方法在RESTFul語義里表示對資源的局部更新晶衷,因此不能保證調(diào)用1次與調(diào)用N次的結(jié)果相同(如:被更新的資源某個屬性隨著不同的調(diào)用次數(shù)在變化),所以不是冪等的锹漱,同時也不是安全的哥牍。
  • DELETE方法用于刪除資源,調(diào)用1次或N次的結(jié)果都是相同的挠说,因此是冪等的蛙奖,但不是安全的。

如何設(shè)計符合冪等性的接口

設(shè)計冪等性接口的關(guān)鍵在于保證接口不論是被調(diào)用1次還是N次琐脏,它對資源所產(chǎn)生的影響都是相同的。
從上述HTTP方法的冪等性總結(jié)中可以得知掐暮,HTTP協(xié)議的POST和PATCH方法都不是冪等性的(但是我們卻經(jīng)常會在RESTFul接口中使用到它們)路克,那是否就意味中無法將POST和PATCH方法設(shè)計為冪等性接口了呢?答案顯然是否定的灰羽。在上述例子中廉嚼,可以將訂單ID也作為方法參數(shù)之一,如:pay(long account, int money, long order)傍念,這樣在服務端確保一個訂單只會被支付一次(訂單號是全局唯一的),那么無論該方法被調(diào)用1次還是N次結(jié)果都是一樣的秦陋,也就保證了接口的冪等性驳概。當然,在哪些沒有訂單號的場景稚照,可以為接口操作生成一個全局唯一的處理號ID上枕,并把該處理號ID作為方法參數(shù)之一辨萍,這樣在服務端確保一個處理號ID只會被執(zhí)行一次就保證了接口的冪等性锈玉。
符合冪等性的接口調(diào)用流程描述如下圖所示:

2.png

寫在最后

雖然說設(shè)計符合冪等性的接口在某些場合可以降低系統(tǒng)的復雜性(如:可以不用引入分布式事務)默终,但是并非在所有場合的問題都能通過冪等性接口解決土陪,在必要的時候依然需要引入分布式事務處理這樣的框架。我們不要也不能把接口冪等性作為萬能的解決辦法源哩,但是励烦,我們在設(shè)計接口時盡量考慮符合冪等性處理是非常有價值的。

【參考】

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市友多,隨后出現(xiàn)的幾起案子纵柿,更是在濱河造成了極大的恐慌,老刑警劉巖荆忍,帶你破解...
    沈念sama閱讀 212,816評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件屈呕,死亡現(xiàn)場離奇詭異,居然都是意外死亡嗽桩,警方通過查閱死者的電腦和手機碌冶,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,729評論 3 385
  • 文/潘曉璐 我一進店門罐氨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人租悄,你說我怎么就攤上這事⊥飧担” “怎么了?”我有些...
    開封第一講書人閱讀 158,300評論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長熙尉。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么椎椰? 我笑而不...
    開封第一講書人閱讀 56,780評論 1 285
  • 正文 為了忘掉前任译荞,我火速辦了婚禮堤瘤,結(jié)果婚禮上浆熔,老公的妹妹穿的比我還像新娘慎皱。我一直安慰自己,他們只是感情好夺欲,可當我...
    茶點故事閱讀 65,890評論 6 385
  • 文/花漫 我一把揭開白布市埋。 她就那樣靜靜地躺著,像睡著了一般弓千。 火紅的嫁衣襯著肌膚如雪镣陕。 梳的紋絲不亂的頭發(fā)上岂嗓,一...
    開封第一講書人閱讀 50,084評論 1 291
  • 那天侈咕,我揣著相機與錄音楼眷,去河邊找鬼。 笑死张吉,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的酵幕。 我是一名探鬼主播芳撒,決...
    沈念sama閱讀 39,151評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼舌菜,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了爱咬?” 一聲冷哼從身側(cè)響起精拟,我...
    開封第一講書人閱讀 37,912評論 0 268
  • 序言:老撾萬榮一對情侶失蹤师枣,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,355評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡解阅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,666評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,809評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡煌往,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情院水,我是刑警寧澤,帶...
    沈念sama閱讀 34,504評論 4 334
  • 正文 年R本政府宣布场斑,位于F島的核電站漏隐,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏爽柒。R本人自食惡果不足惜浩村,卻給世界環(huán)境...
    茶點故事閱讀 40,150評論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧策肝,春花似錦棺禾、人聲如沸膘婶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽浙值。三九已至,卻和暖如春檩小,著一層夾襖步出監(jiān)牢的瞬間开呐,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,121評論 1 267
  • 我被黑心中介騙來泰國打工规求, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留筐付,地道東北人。 一個月前我還...
    沈念sama閱讀 46,628評論 2 362
  • 正文 我出身青樓阻肿,卻偏偏與公主長得像瓦戚,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子丛塌,可洞房花燭夜當晚...
    茶點故事閱讀 43,724評論 2 351