我发布了一个关于REST中无处不在的语言和成熟度级别的问题。
经过一些广泛的编码,我意识到可以从这篇文章中得到更多的问题。
例如,如果我使用的是基于资源的API,那么API端点在基本GET中看起来就像http://domain.com/products/555。
如果我想更新一个资源,它应该如下所示
http://domain.com/products/555 PUT
期待一个有效负载,例如
{
id: 555,
name: "Sample product",
availability: 111
}为了使用DDD和普适语言的所有功能,域模型应该包含以下方法:
因此,如果API期望这个有效负载,我正在考虑两个可能的解决方案。
( a)将此单个更新端点拆分为多个,如:
b)在应用层中有额外的逻辑,以便
有什么推荐的方法来处理这个场景吗?
发布于 2016-06-15 12:22:54
我将尽量详尽地介绍您可能使用的解决方案。正如您所写的,我认为产品具有以下属性: id、名称、可用性
设计一个资源
GET返回产品id 555的当前名称。PUT newname用newname修改产品id 555的当前名称GET返回当前可用性。PUT 99修改99的当前可用性。..。等等..。
请注意,这些资源不是“面向方法的”,它们对应的概念(产品的名称、可用性等)可以更新、检索、删除等,并且不受特定功能的限制。
还请注意,当资源接收GET或PUT请求时,我没有描述不同的内部方法调用。这完全是正交的。在答案的末尾,我会给它写个小便条。
这种方法的主要缺点是:要更新x属性,客户端需要发送x个请求。您可以清楚地看到,客户端这样做可能很乏味,而且带宽消耗也很大。但如果没问题,那就去吧。
的资源
GET返回这些属性。要更新它们,您有两种可能:进行更新
PUT方法旨在完全更新资源表示形式。这意味着客户端需要发送有效负载中产品的所有属性。
假设当前资源/产品/555的表示是:
{ "name": "bread", "availability": 10 }如果只想更新到99的可用性,则需要发送资源的完整表示形式,如下所示:
PUT /products/555 { "name": "bread", "availability": 99 }这种方法的主要缺点是:希望更新一个字段的客户端需要发送整个资源表示。
进行更新
补丁动词旨在部分更新资源表示形式。考虑到当前产品的表示形式是{ "name": "bread", "availability": 10 }。如果客户端只想更新availability,它将发送:
PATCH /products/555 { "availability": 42 }小心点,因为补丁不是幂等的。这意味着这一请求:
PATCH /products/555 { "availability": 42 }可以产生以下资源表示:
{ "name": "bread", "availability": 42 }或
{ "name": "sugar", "availability": 42 }因此,它破坏了幂等性..。PUT保证:)!(因为使用PUT,您可以在请求体中发送完整的表示)
如果产品资源有,您还可以更新几个属性。这显然比1中描述的解决方案消耗的带宽要少。
如前所述,方法调用与资源的设计是正交的。
在您的例子中,您有一些细粒度的方法来更新Product的一个属性.没关系。
但是您可以将它封装在粗粒度的方法中,如下所示:
Product updateProduct(Product p) {
p.updateName();
p.changeAvailability();
...
return p;
}发布于 2016-06-15 13:01:50
有什么推荐的方法来处理这个场景吗?
您需要查看Jim关于Restful系统 DDD的讨论。
基本方案--修改聚合,将文档(也称为消息)传递到HTTP端点,而对聚合所做的更改是文档操作的副作用。
因此,解决方案(a)正朝着正确的方向发展。
我认为,每个命令都应该有一个单独的资源--我的意思是,您应该能够区分重复命令和两个参数相同的命令(在愉快的路径上,这并不重要--但如果您在不可靠的网络(如TCP/IP)上发送命令,则可能很重要)。
实际上,这意味着每个命令都有自己的、客户端生成的唯一标识符,这个标识符在URI中使用,就像产品id用于标识产品资源一样。
因为每次都要传递命令的完整表示形式,所以适当的方法是PUT (或者post,如果PUT不支持的话)。
在此之后,这只是URI设计的问题;但必须满足URI必须弥补您选择从消息本身的正文中删除的任何数据的约束。但以下任何一项都可能是合适的
PUT /commands/a3a14d61-5343-442f-8c2b-febc4d9d8164
PUT /products/555/commands/a3a14d61-5343-442f-8c2b-febc4d9d8164
PUT /products/555/{commandType}/a3a14d61-5343-442f-8c2b-febc4d9d8164
PUT /products/555/commands/{commandType}/a3a14d61-5343-442f-8c2b-febc4d9d8164
PUT /products/555/{commandType}/commands/a3a14d61-5343-442f-8c2b-febc4d9d8164休息不关心什么颜色的自行车棚是,所以去与任何最适合你现有的指导方针。
https://softwareengineering.stackexchange.com/questions/322282
复制相似问题