[英]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.