当前位置:  开发笔记 > 编程语言 > 正文

在REST中需要更多动词时该怎么办

如何解决《在REST中需要更多动词时该怎么办》经验,为你挑选了1个好方法。

我的另一个类似的问题,但讨论偏离了我正在讨论的问题.

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

费用报告可能如下所示:

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"}]
}

看起来很好,对吗?这是费用报告文件的样子.

如果要更新它,可以执行以下操作:

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

如果您要批准它,您可以这样做:

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

但是,如果您想要更新报告并同时批准该怎么办?我们怎么做?如果你只想批准,那么做POST一些/er/1/approval有意义的事情.

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

我们也可以提交特殊领域,但这似乎也有点hacky.如果我们这样做,那么为什么不发送带有set_title或者属性的数据add_to_cost

我们可以创建一个新的资源来进行更新和批准,但是(1)我想不出如何在没有动词的情况下命名它,以及(2)根据可以对哪些动作进行命名来定义资源似乎是不对的.它(如果我们添加更多动作会怎么样?)

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

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

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

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

    抑制或发送通知(发送电子邮件,聊天,其他系统,等等)

    覆盖一些验证(最高费用,晚宴参加者姓名)

    触发在文档中没有表示的后端工作流.

它也是一个性能问题.HTTP呼叫到达网络(如果您有高延迟或连接时可能会出现问题),因此您可以制作的越少越好.



1> Cheeso..:

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

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

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

设定数据:

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

批准:

{ action: "approve" }

新增项目:

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

等等


来自Fielding的Ch5,它定义了REST,

(请求的)参数包括请求控制数据,指示请求目标的资源标识符和可选表示.

...和...

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


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

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

但你可能想要概括它,以便它是:

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

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

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

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


你需要非常小心这种模式.通过创建与HTTP谓词重叠的动词,它很容易违反统一界面.例如{action:"delete"}我认为只有在没有其他方式以更加面向资源的方式对行为进行建模时才应采用这种方法.使用"动作"参数的缺点是嵌入链接比仅基于网址的请求要困难得多.
@Cheeso是的请求包括控制数据.Http称这些东西是HTTP头和Http方法.请求还可以包含表示.根据我对你的帖子的理解,你将控制数据放在表示中.菲尔丁说那可以吗?
据我所知,Fielding没有规定控制数据只在HTTP Headers中传递.当然不在REST章节中,它独立于HTTP定义.您将任何HTTP传输的内容定义为"表示"; 这就是我们不同意的地方.我不认为这是REST所要求的.事实上,我不知道一个专门将REST应用于HTTP的文档(REST的HTTP"绑定"),这可能是规定的.还有更多....
即使您坚持将HTTP有效负载定义为REST的HTTP绑定中的"表示",REST也不要求传输的表示是获取消息的资源的表示.在第5.2.1.2节中,REST章节说消息中的表示可以是*任何*,包括"客户端查询表单中输入数据的表示".基于此,很明显,传输的表示也可以编码请求或命令,正如我上面所推荐的那样.释放你的心灵.
推荐阅读
Life一切安好
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有