細說RESTful API之冪等性

2022-03-22 16:45:49 字數 2326 閱讀 6251

冪等性原本是數學中的含義,表示式的是n次變換與1次變換的結果相同。

而restful api中的冪等性是指呼叫某個方法1次或n次對資源產生的影響結果都是相同的,需要特別注意的是:這裡冪等性指的是對資源產生的影響結果,而不是呼叫http方法的返回結果。

舉個例子,restful api中的get方法是查詢資源資訊,不會對資源產生影響,所以它是符合冪等性的,但是每次呼叫get方法返回的結果有可能不同(可能資源的某個屬性在呼叫get方法之前已經被其他方法修改了)。

實際上,在分布式架構中的api冪等性不僅僅針對restful介面,而是對所有型別的介面適用,目的是為了確保呼叫1次或n次介面時對資源的影響結果都是相同的。

介面的冪等性確保了無論呼叫1次還是n次對資源的影響都是相同的,這在某些場合下是非常有用的。

舉個例子,有這樣乙個介面方法:pay(long account, int money),該方法用於銀行卡扣款支付,引數account為賬戶id,money為需要扣除的錢數。當使用者從網頁上點選支付按鈕時,在該方法的實現邏輯中需要從指定賬戶中扣除對應的商品價錢。如果支付操作已經成功執行,但是響應訊息因為某種原因未能及時返回給客戶端,這時候給使用者的體驗是可能是未支付成功,如果此時再次點選支付按鈕,那麼將再一次執行該方法,結果可能會導致使用者只買了一件商品卻花了雙份的錢,這當然是不合理的。整個流程如下圖所示:

當然,就上述例子的場景,為了避免使用者重複支付,是可以通過別的方式解決的,比如:分布式事務,或者根據支付狀態提示給予使用者進行提示等等。

但是,如果引入了分布式事務,那麼將帶來實現上的複雜性,而且會影響到介面效能;而採取提示資訊的方式並不能百分之百確保使用者不會重複支付,存在一定的風險。而如果介面符合冪等性,即:對同乙個訂單無論是執行一次支付還是多次支付,在服務端都確保只會扣一次款,那麼既不需要引入分布式事務的複雜性,也能從根本上解決重複支付的問題,這也就是介面符合冪等性的價值所在。

總而言之,介面符合冪等性在可以降低系統實現的複雜性,並能保證資源狀態的一致性。

restful風格的介面設計本質上使用的是http協議方法,因此,restful介面方法的冪等性指的就是http方法的冪等性。

常用的http方法有:options(獲取伺服器資訊),head(請求資源首部資訊),get(獲取資源),post(建立資源),put(更新資源全部資訊),patch(更新資源部分資訊),delete(刪除資源)。那麼,這些http方法的冪等性又是什麼樣的呢?

除了冪等性之外,http方法的安全性是指不對資源產生修改。

如下是常用http方法的冪等性和安全性總結:

http方法名稱

是否冪等

是否安全

optionsyy

headyy

gety

yputyn

deleteyn

postnn

patchnn

從上述**中可以看出,http方法的冪等性和安全性並不是同乙個概念,如下是對個各個方法的冪等性和安全性解釋:

設計冪等性介面的關鍵在於保證介面不論是被呼叫1次還是n次,它對資源所產生的影響都是相同的。

從上述http方法的冪等性總結中可以得知,http協議的post和patch方法都不是冪等性的(但是我們卻經常會在restful介面中使用到它們),那是否就意味中無法將post和patch方法設計為冪等性介面了呢?答案顯然是否定的。在上述例子中,可以將訂單id也作為方法引數之一,如:pay(long account, int money, long order),這樣在服務端確保乙個訂單只會被支付一次(訂單號是全域性唯一的),那麼無論該方法被呼叫1次還是n次結果都是一樣的,也就保證了介面的冪等性。當然,在哪些沒有訂單號的場景,可以為介面操作生成乙個全域性唯一的處理號id,並把該處理號id作為方法引數之一,這樣在服務端確保乙個處理號id只會被執行一次就保證了介面的冪等性。

符合冪等性的介面呼叫流程描述如下圖所示:

雖然說設計符合冪等性的介面在某些場合可以降低系統的複雜性(如:可以不用引入分布式事務),但是並非在所有場合的問題都能通過冪等性介面解決,在必要的時候依然需要引入分布式事務處理這樣的框架。我們不要也不能把介面冪等性作為萬能的解決辦法,但是,我們在設計介面時盡量考慮符合冪等性處理是非常有價值的。

【參考】

如何理解restful的冪等性

理解http冪等性

methods/idempotency/ restful 手冊

細說RESTful API之設計原則

1.rest api uri設計的7個準則 1 uri末尾不需要出現斜槓 2 在uri中使用斜槓 表達層級關係 3 在uri中可以使用連線符 提公升可讀性 4 在uri中不允許出現下劃線字元 5 在uri中優先使用小寫字元 6 在uri中不允許出現副檔名,而應該使用content type生命訊息型...

什麼是冪等,什麼情況下需要冪等,如何實現冪等

在微服務架構下,我們在完成乙個訂單流程時經常遇到下面的場景 乙個訂單建立介面,第一次呼叫超時了,然後呼叫方重試了一次 在訂單建立時,我們需要去扣減庫存,這時介面發生了超時,呼叫方重試了一次 當這筆訂單開始支付,在支付請求發出之後,在服務端發生了扣錢操作,介面響應超時了,呼叫方重試了一次 乙個訂單狀態...

什麼是冪等,什麼情況下需要冪等,如何實現冪等

在微服務架構下,我們在完成乙個訂單流程時經常遇到下面的場景 乙個訂單建立介面,第一次呼叫超時了,然後呼叫方重試了一次 在訂單建立時,我們需要去扣減庫存,這時介面發生了超時,呼叫方重試了一次 當這筆訂單開始支付,在支付請求發出之後,在服務端發生了扣錢操作,介面響應超時了,呼叫方重試了一次 乙個訂單狀態...