2015-08-19 31 views
22

一個簡單的REST API:REST:使用一個請求更新多個資源 - 標準還是要避免?

  • GET:項/(編號) - 返回該項目的描述給定id
  • PUT:項/(編號) - 更新或與給定的創建項目ID
  • DELETE:項/(編號) - 刪除項目指定id

現在的API擴展的問題:

  • GET:項目過濾器 - 返回所有項ID匹配濾波器
  • PUT:項目 - 更新或創建一組項目由JSON有效載荷描述
  • [DELETE:項目 - 刪除所描述的項目清單通過JSON有效載荷] < - 不正確

我現在是感興趣的DELETE和PUT可通過PUT可以輕鬆訪問操作回收功能/刪除項目/(編號)。

問題:提供這樣的API是否很常見?

替代方案:在單一連接時代,發出多個請求的多個請求很便宜,並且由於更改成功或失敗而工作得更加原子化,但在NOSQL數據庫時代,列表中的更改可能已經發生,即使由於任何原因,請求處理因內部服務器或其他原因死亡。返回 - 項/ {ID}:

一個簡單的REST API:

  • GET

    [UPDATE]

    考慮White House Web StandardsWikipedia: REST Examples以下實施例的API現已旨意後具有給定ID的項目的描述

  • PUT:項目/ {id} - 更新或創建具有給定ID的項目
  • DELETE:項/(編號) - 刪除項目指定id

頂級資源API:

  • GET:項目過濾器 - 返回所有項ID匹配濾波器
  • POST:項目 - 更新或創建JSON有效負載描述的一組項目

PUT和DELETE on/items不受支持和禁止。

使用POST似乎做的是在封閉的資源中創建新項目,而不是替換但附加。

HTTP Semantics POST閱讀次數:

通過附加操作

擴展數據庫凡PUT方法將需要更換整個收集,以便返回的等價表示由HTTP Semantics PUT引:

一個給定表示的成功PUT將表明後續的GET相同的目標資源將導致在200(OK)響應中返回等效表示。

[UPDATE2]

似乎甚至更一致的對多個對象的更新方面的另一種似乎是PATCH方法。

的PUT和PATCH請求之間的差異被反映在服務器處理該封閉實體來修改由Request-URI所標識的資源的方式:PUT和貼片之間的差在Draft RFC 5789如所描述。在PUT請求中,封閉的實體被認爲是存儲在源服務器上的資源的修改版本,並且客戶端正在請求替換存儲的版本。但是,對於PATCH,封閉實體包含一組說明,說明當前駐留在源服務器上的資源如何修改以生成新版本。 PATCH方法影響由Request-URI標識的資源,並且它也可能對其他資源產生副作用;即可以通過應用PATCH創建新的資源,或者修改現有的資源。

因此,與POST相比,PATCH可能也是一個更好的主意,因爲PATCH允許更新,其中POST僅允許附加意思添加而沒有修改的機會。

所以POST似乎是錯在這裏,我們需要把我們的建議API更改爲:

一個簡單的REST API:

  • GET:項/(編號) - 返回該項目的說明給定id
  • PUT:項/(編號) - 更新或創建指定id
  • 刪除項目:項目/(編號) - 指定id
01刪除項目

頂級資源API:

  • GET:項目過濾器 - 返回所有項ID匹配濾波器
  • POST:項目 - 創建一個或多個項目,如由JSON有效載荷描述
  • PATCH:項目 - 創建或更新JSON有效負載所描述的一個或多個項目
+0

可以幫忙:https://github.com/WhiteHouse/api-standards#http-verbs。 BTW,DELETE請求沒有定義的主體語義(http://stackoverflow.com/a/5928241/1225328)。 – sp00m

+0

感謝DELETE信息 –

回答

13

您可以修補集合,例如

PATCH /items 
[ { id: 1, name: 'foo' }, { id: 2, name: 'bar' } ] 

技術上PATCH將標識記錄在URL(請求體中的IE補丁/items/1並沒有,但是這似乎是一個很好的務實的解決方案。

爲了支持刪除,創建和更新中單呼,這不是真正的標準REST約定支持一個可能是一個特殊的「批」的服務,讓您裝配在一起來電:

POST /batch 
[ 
    { method: 'POST', path: '/items', body: { title: 'foo' } }, 
    { method: 'DELETE', path: '/items/bar' } 
] 

返回狀態碼,用於每個嵌入式請求的響應:

[ 200, 403 ] 

不是真正的標準,但我已經做到了,它的工作原理。

+0

一個批次的想法很有趣。你是如何實現它的?這是真正的派遣還是內部處理?當考慮到今天只需要一個連接時,發出多個請求而不是單個請求會導致這種性能損失(延遲,帶寬)? –

+0

最初,它是在內部處理的,與單個查詢分開處理,主要是出於性能原因。 (您可以進行優化,如執行單個SQL查詢,而不是N個查詢。)但由於一些混淆不一致性,最終重構了這種結構,以便在批處理命令和「真實」原子命令之間有效地共享相同的代碼。這對性能有點影響,儘管如果必要的話,可以通過一些緩存和優化來緩解這一點。 – mahemoff

+0

如果您可以使用HTTP/2,則該方案可能不必要,因爲多個調用的性能開銷可能相當低。 – mahemoff

1

就我所瞭解的REST概念而言,它涵蓋了使用一個請求更新多個資源。其實這裏的訣竅是假設一個容器圍繞這些多個資源並將其作爲一個單一資源。例如。您可以假設ID列表標識了包含其他幾個資源的資源。

在那些examples in Wikipedia他們也談論複數資源。

+1

在維基百科示例中,他們指出PUT和POST的處理方式不同,應該使用POST編寫一個或多個新實體。 –

相關問題