当您在 REST 中需要更多动词时该怎么办 [英] What to do when you need more verbs in REST

查看:37
本文介绍了当您在 REST 中需要更多动词时该怎么办的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我还有另一个类似的问题,但讨论偏离了我遇到的问题.

There is another similar question to mine, but the discussion veered away from the problem I'm encounting.

假设我有一个处理费用报告 (ER) 的系统.您可以创建和编辑它们、添加附件以及批准/拒绝它们.

Say I have a system that deals with expense reports (ER). You can create and edit them, add attachments, and approve/reject them.

费用报告可能如下所示:

An expense report might look like this:

GET /er/1
=>
{"title": "Trip to NY", "totalcost": "400 USD",
 "comments": [
   "john: Please add the total cost",
   "mike: done, can you approve it now?"
   ],
 "approvals": [
   {"john": "Pending"}, {"finance-group": "Pending"}]
}

看起来不错,对吧?这就是费用报告文档的样子.

That looks fine, right? Thats what an expense report document looks like.

如果你想更新它,你可以这样做:

If you want to update it, you can do this:

POST /er/1
{"title": "Trip to NY 2010"}

如果你想批准它,你可以这样做:

If you want to approve it, you can do this:

POST /er/1/approval
{"approved": true}

但是,如果您想同时更新报告批准它怎么办?我们怎么做?如果您只想批准,那么对 /er/1/approval 之类的内容执行 POST 是有意义的.

But, what if you want to update the report and approve it at the same time? How do we do that? If you only wanted to approve, then doing a POST to something like /er/1/approval makes sense.

我们可以在 URL 中放置一个标志,POST/er/1?approve=1,并将数据更改作为正文发送,但该标志似乎不是 RESTful.

We could put a flag in the URL, POST /er/1?approve=1, and send the data changes as the body, but that flag doesn't seem RESTful.

我们也可以放置特殊的字段来提交,但这似乎也有点hacky.如果我们这样做了,那么为什么不发送带有 set_titleadd_to_cost 之类的属性的数据?

We could put special field to be submitted, too, but that seems a bit hacky, too. If we did that, then why not send up data with attributes like set_title or add_to_cost?

我们可以创建一个用于更新和批准的新资源,但是 (1) 我想不出如何在没有动词的情况下命名它,以及 (2) 根据可以执行的操作来命名资源似乎不正确完成它(如果我们添加更多动作会发生什么?)

We could create a new resource for updating and approving, but (1) I can't think of how to name it without verbs, and (2) it doesn't seem right to name a resource based on what actions can be done to it (what happens if we add more actions?)

我们可以有一个 X-Approve: True|False 标题,但标题似乎是不适合这项工作的工具.如果不在浏览器中使用 javascript,也很难获得设置的标头.

We could have an X-Approve: True|False header, but headers seem like the wrong tool for the job. It'd also be difficult to get set headers without using javascript in a browser.

我们可以使用自定义媒体类型,application/approve+yes,但这似乎并不比创建新资源更好.

We could use a custom media-type, application/approve+yes, but that seems no better than creating a new resource.

我们可以创建一个临时的批量操作"url,/er/1/batch/A.客户端然后发送多个请求,可能POST/er/1/batch/A更新,然后POST/er/1/batch/A/approval批准,然后POST/er/1/batch/A/status 结束批处理.在后端,服务器将所有批处理请求排在某处,然后在收到结束批处理"请求时在同一个后端事务中处理它们.显然,这样做的缺点是它引入了很多复杂性.

We could create a temporary "batch operations" url, /er/1/batch/A. The client then sends multiple requests, perhaps POST /er/1/batch/A to update, then POST /er/1/batch/A/approval to approve, then POST /er/1/batch/A/status to end the batch. On the backend, the server queues up all the batch requests somewhere, then processes them in the same backend-transaction when it receives the "end batch processing" request. The downside with this is, obviously, that it introduces a lot of complexity.

那么,有什么好的、通用的方法可以解决在单个请求中执行多个操作的问题?一般,因为很容易想象可能在同一请求中执行的其他操作:

So, what is a good, general way to solve the problem of performing multiple actions in a single request? General because its easy to imagine additional actions that might be done in the same request:

  1. 禁止或发送通知(发送到电子邮件、聊天、其他系统等)
  2. 覆盖一些验证(最高费用、参加晚宴的人的姓名)
  3. 触发在文档中没有表示的后端工作流.

这也是一个性能问题.HTTP 调用会访问网络(如果您有高延迟或不稳定的连接,这可能是一个问题),因此您可以调用的次数越少越好.

Its also an issue of performance. HTTP calls hit the network (which could be a problem if you have high latency or a flaky connection), so the fewer of them you can make, the better.

推荐答案

REST 架构说资源由服务器管理并由 URL 标识.

The REST architecture says that a resource is managed by the server and identified by a URL.

因此,/er/1/approval 不是一个合理的 URL 或模型,除非您有一个在服务器端管理和操作的批准对象或实体.在我看来,实体是费用报告本身,这意味着 /er/1 是您的 URL 路径.

In that light /er/1/approval is not a reasonable URL or model to use, unless you have an approval object or entity that you manage and manipulate on the server side. Seems to me the entity is the expense report itself, which means, /er/1 is your URL path.

现在,对于动词...您可以向该资源发送(POST)您喜欢的任何消息.

Now, as for verbs... you can send (POST) any message you like to that resource.

设置数据:

{ action: "modify", data: { purpose : "Club hopping" } }

批准:

{ action: "approve" }

添加项目:

{ action:"additem", data: { amount:72.13, category:113, note:"client dinner" }}

等等.

来自 Fielding 的 Ch5,它定义了 REST

(请求的)输入参数由请求控制数据、指示请求目标的资源标识符和可选表示组成.

The in-parameters (of a request) consist of request control data, a resource identifier indicating the target of the request, and an optional representation.

……还有……

控制数据定义了组件之间消息的目的,例如请求的操作或响应的含义.它还用于参数化请求并覆盖某些连接元素的默认行为.例如,可以通过请求或响应消息中包含的控制数据来修改缓存行为.

Control data defines the purpose of a message between components, such as the action being requested or the meaning of a response. It is also used to parameterize requests and override the default behavior of some connecting elements. For example, cache behavior can be modified by control data included in the request or response message.

<小时>

因此,如果您想对一个资源执行多个操作,那么您应该在控制数据"中嵌入多个消息或操作请求.在我的示例中,发布的数据类似于:


Therefore if you'd like to perform multiple actions on a resource, then you should embed in the "control data" multiple messages or action requests. In my example, the posted data would be something like:

{ action: "modify", data: { purpose : "Club hopping" } }
{ action: "approve" }

但您可能想将其概括为:

But you'd probably want to generalize that so that it is:

{ actions: [ {action:"modify", data: {...} }, { action:"approve"} ] } 

您的服务器可以对每种特定类型的实体处理的消息或操作由您来定义.

The messages or actions your server can handle on each particular type of entity are up to you to define.

ps:有时 REST 实现使用 HTTP PUT 来创建资源,并使用 POST 来修改或操作现有资源.

ps: sometimes REST implementations use HTTP PUT to create a resource and POST to modify or act on an existing resource.

并且:我喜欢这篇文章,如何喝杯咖啡.

and: I liked the article, How to GET a cup of coffee.

这篇关于当您在 REST 中需要更多动词时该怎么办的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆