REST API,每个资源有多个命令

时间:2011-06-13 20:34:39

标签: api http rest

我对REST API设计有疑问。这是一个简单的(可能太简单)API:

GET /ecommerce/order/123

POST /ecommerce/order (create a new order)

PUT /ecommerce/order/123 (update an existing order)

DELETE /ecommerce/order/123 (cancel order)

但是如果我希望客户输入订单被取消的原因怎么办?我需要将发布数据发送到API,但这不适用于DELETE。为了迎合这一点,我必须将DELETE更改为PUT。然后我会发布两个不同的资源进行更新和取消。

另一种解决方案是更改API:

GET /ecommerce/order/123

POST /ecommerce/order/create (create a new order)

PUT /ecommerce/order/update/123 (update an existing order)

DELETE /ecommerce/order/cancel/123 (cancel order)

我不确定哪个是最佳选择。

关于REST API如何处理单个资源的多个命令,有一个更普遍的问题。

任何输入都将不胜感激!我很快就会在练习中阅读REST,但这个问题正在勉强看着我。

3 个答案:

答案 0 :(得分:6)

一个选项可能是创建新资源。或许CancelledOrder

然后,您可以POST新的CancelledOrder

POST /ecommerce/cancelledOrder
Entity:
    order: /ecommerce/order/123
    reason: "Problem with order"

您还可以/而PUT CancelledOrder

PUT /ecommerce/cancelledOrder/123
Entity:
    reason "Problem with order"

然后,应用程序可以删除订单123或将其状态更新为“已取消”,或执行您的业务规则要求的任何操作。最重要的是,您可能不会直接为DELETE支持/ecommerce/order/N方法,并返回405 Method Not Allowed

PUT解决方案可以使用幂等优势; <{1}}多次PUT总是会导致订单被取消。

应该注意的是,您更改API的建议(例如CancelledOrder)可能不是RESTful,因为您在资源标识符中定义了方法。

答案 1 :(得分:4)

我知道这是一个非常晚的答案,但我建议使用第一组命令,但将cancel order命令更改为:

POST /电子商务/订单/ 123 /取消

这是处理现有资源上的各种操作的通用方法。我不明白为什么订单取消会导致订单本身被删除,至少不会立即删除。用户可能仍希望查看系统中的订单。订单也是您存储取消原因的地方。

答案 2 :(得分:2)

(这个问题很老了,但我只是觉得我会改进它,因为我不喜欢任何解决方案。)

解决方案很简单。将一个理由放入请求的主体。

DELETE /ecommerce/order/123
Content-Type: text/plain
Content-Length: 48

Order was cancelled due to a customer's request.

身体的语义由你来决定。如果您只想要明文原因,我可以使用text / plain,如上所示。如果需要更复杂的元数据,我会进一步复杂化。

在我看来,这比Javaesque类似OrderCancellator.execute(order)更好(因为POST是&#34的名称;执行&#34;)。

请注意,虽然规范并没有说出相关信息,但有些服务器may discard DELETE request's bodydraft on HTTP/1.1 message semantics澄清:

  

DELETE请求上的实体没有定义的语义。注意   在DELETE请求上发送正文可能会导致一些存在   拒绝请求的实现。

另一种选择是发出标题:

DELETE /ecommerce/order/123
X-Reason: Cancelled due to an UFO invasion.

每当选择标题或实体主体时,取决于数据的大小和格式。有些数据适合HTTP标头,有些则不适合。一个肯定可以通过数字票证ID,它不确定字符串(想想Unicode),并且他们的理智中没有人想要在那里传递Base64 JPEG。