[英]REST API: Is it acceptable to PUT to resource containing query param filters?
我正在設計一個僅返回JSON表示形式的API服務。
我的問題的一些背景知識和背景知識...數據庫中的產品在幕后具有一組相關的價格。 價格由( qty
, currency_code
, unit_price
)元組組成。 每組價格都屬於特定的產品和價格表。
這是關系數據庫數據的一瞥。 每行都有( product_id
, price_list_id
, currency_code
和qty
)的唯一約束。 product_id
和price_list_id
都是外鍵。
dev=# SELECT * FROM
price
WHERE
product_id = 1 AND price_list_id = 1 AND currency_code = 'GBP';
id | uuid | product_id | price_list_id | qty | currency_code | unit_price | created | modified
----+--------------------------------------+------------+---------------+-----+---------------+------------+----------------------------+----------------------------
1 | 6fcbbb5b-8e51-4a4c-bf63-270f5d3f1ff8 | 1 | 1 | 1 | GBP | 20417 | 2019-08-15 15:49:19.508808 | 2019-08-15 15:49:19.508808
16 | c044e9fe-bb5f-4996-b8e6-88b4a1b9f125 | 1 | 1 | 2 | GBP | 3453345 | 2019-08-15 15:49:37.896681 | 2019-08-15 15:49:37.896681
17 | c488d372-e58f-4441-a583-281e4c2b1310 | 1 | 1 | 3 | GBP | 312353345 | 2019-08-15 15:49:41.320622 | 2019-08-15 15:49:41.320622
要檢索給定產品的一組價格,我打算對/products/:product_id/prices?price_list_id=1¤cy_code=GBP
資源使用GET
請求。 我希望收到:
[
{ id: "6fcbbb5b-8e51-4a4c-bf63-270f5d3f1ff8", "qty": 1, "unit_price": 20417 },
... etc // 3 items total
]
如果我想為給定的價格( product_id
, price list_id
和currency_code
)更新一組價格,是否可以通過對我用於GET
的同一URI進行PUT
請求來進行完全相反的操作,即PUT /products/:product_id/prices/price_list_id=1¤cy_code=GBP
還是應該使用其他方法?
在具有price_list_id=1
和currency_code=GBP
的GET
請求的上下文中,其作用類似於過濾器。 在使用PUT
請求時,我不確定是否可以使用查詢參數作為過濾器來標識更新資源。
我考慮過的替代方法是:
PUT /products/:product_id/prices
並將price_list_id
和currency_code
放在請求正文中。 例如 {
"price_list_id": "<uuid>",
"currency_code": "GBP",
"data": [
{ "qty": 1, "unit_price": <newprice> },
... /* new set of prices */
]
}
從而刪除所有現有價格,並將其替換為請求正文中的價格。
PUT /products/:product_id/prices/price-lists/:price_list_id
開始看起來很漫長。 products
prices
很多,因此資源的第一部分看起來可以嵌套為子資源。 但是, prices
沒有price-lists
(相反),因此將price-lists
作為price-lists
的子資源是沒有意義的。
PUT /prices/:price_id
。 這意味着我必須首先檢索一個列表,將它們一個一個地刪除,然后分別更新價格。 這不是一個很好的解決方案,因為我想對價格作為一個整體進行操作。 我還希望將整個集合替換掉或完全替換掉。
您要發送PUT請求的網址應該是您要更新的內容的“身份”。 因此,包含信息以在請求正文中定位資源是沒有意義的。
服務器“定位”您正在更新的資源所需的所有信息都應位於資源定位器中(即url!)。
從HTTP協議角度來看,所有這些都完全可以:
PUT /products/:product_id/prices?price_list_id=1¤cy_code=GBP
PUT /products/:product_id/prices/price-lists/:price_list_id
PUT /prices/:price_id
您的ID是否位於url的查詢部分的路徑部分並不重要,應該無關緊要。 出於查找資源的目的, /article/5
和/article?id=5
之間沒有區別。
因此,您應該根據自己API的一致性,用戶友好性等來選擇哪一個。
有趣的是,您不喜歡選項2太冗長,但是您可以選擇選項1,盡管它更長;)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.