我在一个产品组中有一个产品集合,例如:
product-groups/123/products
如果我需要添加到集合中,可以通过PUT 只传递某些产品吗?
如果我需要从集合中删除某些产品,可以通过DELETE 传递过滤器数据(ID数组)吗?
秉承ReST精神实现功能的最佳方法是什么?
编辑:项目是指向单独实体(基本上是产品ID)的链接。
我在一个产品组中有一个产品集合,例如:
product-groups/123/products
如果我需要添加到集合中,可以通过PUT 只传递某些产品吗?
如果我需要从集合中删除某些产品,可以通过DELETE 传递过滤器数据(ID数组)吗?
秉承ReST精神实现功能的最佳方法是什么?
编辑:项目是指向单独实体(基本上是产品ID)的链接。
Answers:
通常,您有一个端点表示x的整个集合:
/products
假设您要更新单个产品,然后将其放置到/products/{id}
。如果您要部分更新单个产品(而不是更新每个字段),则也可以使用PATCH到/products/{id}
。删除单个实体(DELETE to /products/{id}
)也是如此。
如果要定位单个资源,则可以通过路径限定要修改的单个资源。
破坏方案的唯一动作是资源的创建。创建资源时,您将整个集合作为目标,说POST到/products
。
也就是说,应该明确的是,影响整个集合的操作目标应该转到适当的集合端点。
例如,您要检索红色的产品子集,则要求
GET来/products?colour=red
。
因此,如果要删除所有这些,则请DELETE /products?colour=red
。或者,如果您想通过删除某些产品id
,则可以删除 /products?id=1&id=2&id=3
。
怎么样批量创建 ressources的?POST您的收藏[{...},{...},{...}]
干脆/products
。这同样适用于PUT和PATCH。
那真的很简单。
要回答您的问题:
如果我需要添加到集合中,可以通过PUT仅传递某些产品吗?
不仅可以,还建议您这样做。
如果我需要从集合中删除某些产品,可以通过DELETE传递过滤器数据(ID数组)吗?
没关系。正如Eneko Alonso所写的那样,有时通过“控制器” 端点封装了批量操作,即使用POST来触发(复杂)操作。
PATCH
,并通过进行完全替换PUT
。
通常,REST方法旨在在单个实体/对象(CRUD)上运行。
有几种选择:
第一个遵循REST标准,但是可能很昂贵,因为您的收集对象/实体可能非常大(更新拥有数千个产品的组仅添加/删除一个产品将是一个沉重的要求)。
第二个选项是许多API首选的,这是将REST扩展到CRUD操作之外的一种方法。
例如:
GET product-groups/123/products (list all the products in the group)
POST product-groups/123/products/append (POST a list of new product ids to append to the group)
POST product-groups/123/products/remove (POST a list of product ids to remove from the group)
许多API始终使用POST进行此扩展操作,但没有任何限制可以使用其他http方法(除了GET和DELETE的局限性之外,它具有一个空的正文)
products/collection
返回项目的“信封”和通过PUT更改信封内容的“扩展名”,是否可以更加面向资源?就像,“这正是我想要集合中的项目的样子”。
仅用于精确的先前答案/评论。
据我所知,POST是将单个元素添加到集合中的方法。
反过来,DELETE是从集合中删除单个元素的方法。两种方案都是完全RESTful的。
但是,您应该使用适当的URI来引用单个元素或整个集合。
例如,要将元素添加到集合中,您应该将数据发布到以下URI:
要从集合中删除单个产品,您可以使用DELETE方法将请求发送至以下内容:
PATCH方法可用于更新集合中的某些元素。例如,当您只需要更新一个元素中的一个字段时。为很大的集合放置完整的资源表示形式可能是非常昂贵的操作。
原则上,所有RESTful操作对集合都有效,但是请确保您了解动词的语义如何应用于集合:
PUT是完全替代品。
/item/{id}
),然后将name
其忽略,则应将其清除或设置为null或类似的内容。虽然可以使用PUT添加项目,但必须发送“所有”项目。发送“某些”项目应导致删除(我想这不是OP想要的)。
DELETE更直观。删除集合或其任何过滤的子集是有效的。仅过滤器中包含的项目应受到影响。
PATCH也有效。从理论上讲,您应该提供“操作”列表。例如,从技术上讲,您应该发送以下内容:
[{
"action": "update",
"id": <id>,
"value": {...}
},{
"action": "add",
"value": {...}
}, ...]
在实践中,更常见的情况是看到一个API接受部分对象列表,其中使用UPSERT(更新或插入)逻辑处理各项的对象。
从技术上讲,POST应该“根据资源自身的特定语义”处理输入。
{resource}/activate
。注意:在集合上使用非GET操作时,请仔细考虑成功和失败的定义。REST并没有给您传达部分成功的好方法。一个很好的默认值是假设您将在成功或不成功的事务中运行该操作。如果这不是您想要的,则可能不应该直接与集合进行交互。