我该如何使用REST简单地追加资源属性?假设我有customer.balance,balance是一个整数。我只想告诉服务器将5添加到当前余额中。我可以用RESTful方式实现吗?如果可以,怎么做?
请记住,客户端不知道客户的现有余额,因此它不能只是:
1.获取客户 2.customer.balance += 5 3.发布客户
(上述方法还存在并发问题。)
这是我回答你其他问题的的一个更简单的变体。
我认为如果你按照以下步骤进行,仍然符合REST的限制。然而,我也很想知道其他人对这种情况的看法,所以希望能听到其他人的意见。
你的URI将是:
/customer/21/credits
<credit>5</credit>
)通过POST请求发送到URI,服务器可以获取客户的余额并将其与提供的值相加。此外,你还可以支持负数信用额度(例如<credit>-10</credit>
);/customer/21/credits
不必支持所有方法,只支持POST即可。如果一个资源已经在原始服务器上创建,则响应应该是201(已创建),并包含一个描述请求状态和引用新资源的实体以及一个位置标头。
技术上说,你在这里并没有创建一个资源,而是向客户的余额中添加(这实际上是系统中所有以前信用额度的聚合)。由于你没有保留信用额度(假设),你实际上无法返回对新“创建”的信用额度资源的引用。你可能可以返回客户的余额或<customer>
本身,但这对客户端来说有点不直观。这就是为什么我认为将每个信用额度视为系统中的新资源更容易处理(请参见下文)。
这是我在你其他问题中的答案改编而来。在这里,我将尝试从客户端/服务器正在执行的角度来考虑:
Client:
Builds a new credit resource:
<credit>
<amount>5</amount>
</credit>
POSTs resource to /customer/21/credits
POSTing here means, "append this new <credit>
I'm providing to the list of <credit>
s for this customer.
Server:
/customer/21/credits
+=
s it to the customer's balanceSends response to client:
<credit href="/customer/21/credits/credit-id-4321234">
<amount>5</amount>
<date>2009-10-16 12:00:23</date>
<ending-balance>45.03</ending-balance>
</credit>
/customer/21/credits/[id]
)Clients can retrieve an ordered list of credits, if you support it; e.g. GET /customer/21/credits
might return:
<credits href="/customer/21/credits">
<credit href="/customer/21/credits/credit-id-7382134">
<amount>13</amount>
...
</credit>
<credit href="/customer/21/credits/credit-id-134u482">
...
</credit>
...
</credits>
嗯,除了@Rob-Hruska的解决方案之外,还有其他选择。
基本思路是相同的:将每个借记/贷记操作视为独立的交易。但是我曾经使用过一种后端,支持在json中存储无模式数据,因此我最终定义了API为带动态字段名的PUT。类似于这样:
PUT /customer/21
{"transaction_yyyymmddHHMMSS": 5}
我知道在“信用/借记”上下文中这是不合适的,因为活跃账户可能有不断增长的交易记录。但在我的情况下,我使用这种策略来存储有限的数据(实际上,在驾车旅行期间,我正在存储不同批次的GPS路标)。
缺点:此API风格严重依赖于后端行为的无模式特性。
优点:从语义角度来看,至少我的方法是完全符合RESTful的。
相比之下,@Rob-Hruska的“简单而稍微丑陋”的解决方案1没有有效的位置头返回“201 Created”响应,这不是常见的RESTful行为。(或者,也许我们可以让@Rob-Hruska的解决方案1返回一个虚拟的位置头,指向“410 Gone”或“404 Not Found”页面。这更符合RESTful吗?欢迎评论!)