我正在实现RESTful Web服务,可用的操作之一是reload。它将用于重新加载配置,缓存等。

我们从一个简单的GET开始到这样的URI:${path}/cache/reload(不传递参数,仅调用URI)。我知道不应使用GET请求修改数据。

哪个是用于在RESTful Web服务中调用动作/命令的正确动词?

reload是REST Web服务的命令,可重新加载其自己的缓存/配置/等。它不是将信息返回给客户端的方法。

我想做的可能不是REST,但这仍然需要通过这种方式来完成。 reload方法仅是一个实际示例,在应用程序范围内有意义,并且大多数答案都针对该示例,但是实际上,我只需要知道哪个动词即可触发不执行CRUD但仍会更改数据的操作/ state。

我在以下主题上找到了有关Stack Overflow的详细解答:https://stackoverflow.com/questions/16877968/

评论

“重新加载”是应用程序刷新将要显示的数据的感觉吗?重新加载与仅重新获取数据之间有什么区别吗?

@SeanRedmond不,数据未发送到客户端。实际上,客户端是在对REST Web服务说要执行和内部命令(重新加载)。诸如此类:“数据库中的许多配置已更改,因此REST Web服务现在将它们重新加载到您的内存中。”

跨站点重复:stackoverflow.com/q/15340946/319403

您是否考虑过在适当的请求上使用标头参数?这听起来很像是缓存刷新...

在我看来,您根本没有实现RESTful Web服务。 RESTful是一种体系结构原理,您的这种方法根本不是RESTful。这有什么害处吗?一点也不。我总是指向这个API:api.fattureincloud.it/v1/documentation/dist,所有方法都在POST中。它是RESTful的吗?一点也不。它行得通吗?是的,它的确是意大利电子发票最常用的API之一。

#1 楼

我认为此操作没有合适的动词,因为此事务并不是真正的“ RESTful”。 “ s”和“ t”代表“状态转移”,此处未转移任何内容。或者,换一种说法,按照最严格的定义,诸如PUT和POST之类的动词始终与名词一起使用,而“ reload”仅具有动词。

此重新加载可能不是RESTful的,但可能仍然很有用,您只需要选择一种方法,然后忍受或解释这是不寻常的。 GET可能是最简单的。但是,在评论中有相当多的怀疑态度,因此您应该考虑是否需要执行此重新加载操作,因为其他事情并未完全执行应做的事情。

评论


我同意这不是RESTful的,但可能有用。我认为您应该建议使用PUT,因为这可能是幂等的,但不是nullimpotent。

–亚伦·格林瓦尔德(Aaron Greenwald)
2014年11月3日在21:01

@Aaron,幂等和零幂的比较都很好,但是如何确定什么时候不幂呢?

– Craig
15年7月30日在20:01

@Craig如果多次运行具有相同的效果,则运行一次具有相同的效果。如果运行一次或多次对服务器具有与运行零次相同的效果,则它是无效的。 en.wikipedia.org/wiki/Idempotence

–亚伦·格林瓦尔德(Aaron Greenwald)
2015年8月1日在4:21

@AaronGreenwald“无能的” [not-im-poht-nt] [not-im-pawr-tnt]-形容词-1.玩单词“不重要”,形容词“重要”的反义词。 2.幽默…;-)

– Craig
2015年8月1日在6:32



@克雷格,我完全错过了:)

–亚伦·格林瓦尔德(Aaron Greenwald)
15年8月2日在19:35

#2 楼

如果您想成为RESTful,请不要考虑动词来执行操作,请想一想客户在完成某件事之后资源所处的状态。上面的示例中,您有一个正在发送电子邮件的电子邮件队列。您希望客户端将电子邮件队列置于已暂停或已停止或其他状态。

因此,客户端会将该资源的新状态放入服务器。它可以很简单,就像这个JSON

PUT http://myserver.com/services/email_service HTTP/1.1
Content-Type: text/json

{"status":"paused"}


服务器指出如何从当前状态(例如“正在运行”)变为“已暂停”状态/状态。

如果客户端在资源上执行GET,则客户端应返回其当前处于的状态(例如“已暂停”)。

这样做的原因以及REST之所以如此强大的原因是,您离开了如何使服务器恢复到该状态。

客户端只是说“这是您现在应该处于的状态”,服务器便知道了如何做到这一点。这可能是数据库中的简单翻转。它可能需要数千个动作。客户不在乎,也不必知道。

因此,您可以完全重写/重新设计服务器如何做到这一点,而客户端则不在乎。客户端只需要知道资源的不同状态(及其表示),而无需了解任何内部结构。

评论


就我而言,这是正确的答案。在服务器上刷新数据不是幂等操作,而GET是完全不适合使用的动词。 PUT是最合适的动词,因为可以将操作视为将缓存的“重载状态”更新为“重载”。

– Jez
15年4月27日在15:17

@Jez在这里,我也更喜欢这个答案。坚持使用电子邮件的隐喻,乍一看,想通过将邮件置于“发送”状态而不是仅仅发送(动作)来发送邮件确实很奇怪。但是,如果您考虑一下,那实际上与将其放入“发件箱”是一样的。实际上,当您告诉邮件系统发送邮件时,邮件系统本身可能会在内部对其进行排队。因此,API可以让您将邮件置于“发送”状态,并且API不必对此进行自我解释。

– Craig
15年7月30日在19:57

因此,通过扩展,如果您不希望消息立即发送,则将其置于“已计划”状态,并带有应该发布的日期/时间。如果它不完整,则将其(或默认/隐式)置于“草稿”状态等。

– Craig
15年7月30日在19:57



...虽然我认为在这种情况下我更喜欢POST而不是PUT,因为PUT也应该是幂等的,但是POST不受此约束。

– Craig
15年7月30日在20:28

您可以这样做,但是最终它试图将方形钉插入圆孔中。客户端没有理由需要触发服务器“重新加载”任何东西,那只是糟糕的架构设计。服务器可以在每次调用时或以固定的时间间隔更新其内部状态。依靠客户端告诉服务器重新加载某些独立于资源状态的实际请求的东西不是RESTful体系结构。

– Cormac Mulhall
2015年12月8日在16:16

#3 楼

其他一些答案(包括已接受的答案)建议您使用GET(尽管不是很热情)。

我不同意。

首先,所有其他告诉您这不是理想的并且不是真正的RESTful是正确的。在适当的RESTful场景中,您需要处理服务器上的资源并添加,更新,删除,检索等资源。 PUT应该发送一个表示请求完成时资源应该是什么的有效负载,而POST应该发送一个表示要添加到服务器的资源的有效负载。 GET应该返回服务器上的资源。

您有一个RPC(远程过程调用),它不是RESTful的-您想在服务器上做一些事情。因此,如果您尝试创建一个纯粹的RESTful API,则应重新考虑您的工作。

这就是说,有时候您确实需要稍微修改一下规则。尤其是如果您正在开发不会向公众公开的内部api,则可能会决定权衡是值得的。

如果这样做,我将建议使用PUT或POST,具体取决于RPC是否是幂等的。 SQL UPDATE以及该HTTP POST映射到SQL INSERT,但这并非完全正确。一种更纯净的声明方式是HTTP PUT应该是幂等的,而HTTP POST不必是幂等的。这意味着您可以多次调用相同的PUT请求,而不会产生副作用。一旦调用它,再次调用它是无害的。但是除非您打算这样做,否则您不应重复调用POST请求-每个POST都会再次更改服务器上的数据。

对于您的情况,如果您需要此重载功能,我建议您使用PUT,因为它听起来像幂等。但是我仍然敦促您考虑其他人对根本不需要它的看法。

#4 楼

POSTPUT是用于将实体提交到Web服务器的HTTP动词。对于PUT,提交的实体是给定URI上资源的(新)表示形式,不符合您的要求。 POST适用于传统的表单处理程序,其中实体是资源的辅助数据,因此是赢家。该实体将包含命令或操作(例如“ action = reload”)。

也就是说,有问题的命令可能不应该通过REST接口公开。听起来好像有必要进行“重新加载”,因为可以通过其他一些渠道(例如文件系统,DB客户端)更改数据。缓存应该是透明的。而且,HTTP请求应该是原子的,甚至考虑通过其他渠道发送的消息。提供用于配置设置的“重新加载”命令似乎不必要。要求它是一种脆弱的设计。通过另一个通道进行更新后,将“重新加载”暴露给清理是肮脏的,因为一个通道不包含整个对话。而是考虑以下方法之一:


完全通过REST进行更新
将命令公开到另一个通道
使动作自动化

其中一些选项可能不可行,具体取决于存在其他限制。

另请参阅“ REST中的PUT与POST”。

评论


谢谢。我删除了编辑的“内部”,因为实际上“重新加载”方法旨在公开使用。我只是试图表示它指的是Web服务本身。我认为发布“行动”将是一个很好的方法。

– Renato Dinhani
2014年11月2日,凌晨3:40

@RenatoDinhaniConceição:即使没有“内部”,它仍然会闻起来。您也许应该问一个新问题,即设计是否是一个好的设计。

– outis
2014年11月2日,下午5:02

#5 楼

我会争辩为什么为什么客户请求会明确需要调用以刷新类似的内容。听起来这应该是更典型的GET实现(即Pull数据,但是该服务在提取数据之前刷新数据)上的隐藏逻辑,或者应该是后端中远离客户端的另一个触发器。毕竟,数据/配置只需要在后续调用中保持最新状态,因此我将更倾向于对数据刷新的懒惰与渴望的调用。显然,我在这里承担了很多责任,但是我将退后一步,重新评估这种显式且独立的调用的必要性。

评论


看我的编辑。 “ reload”不是返回数据的命令。它指的是REST Web服务本身。概括而言,我的问题是关于REST Web服务中的触发操作。其他示例可以是:email_queue / stop_sending_emails。我只想使用RESTful接口向某物发出命令。

– Renato Dinhani
2014年11月2日,下午2:52

我仍然同意。在本地进程上调用SIGHUP是有意义的,因为计算机应该信任可以访问该信号的本地登录人员。但是对于无状态,可访问Internet的协议呢?也许Web服务应该根据需要通过轮询或文件监视自动重新加载。此调用应该完全没有必要。

–user22815
2014年11月2日,3:50

我同意。诸如配置和缓存之类的事情对于客户端来说是透明的。也许您应该给我们更详细的描述将调用您的端点的情况。

–本杰明·霍奇森(Benjamin Hodgson)
2014年11月3日在21:26

#6 楼

为什么不将动作视为资源。因此,由于您要更新缓存,因此可以在系统中发布新操作。请注意,您可以扩展它,并在数据库(或任何存储)中记录日期,状态,用户等的实际操作。这只是我的想法。 /> / actions / {action}

特定于资源类型的操作
/ actions / {resource} / {action}

特定于资源的操作
/ actions / {资源} / {id} / {action}

对于您而言,缓存可能是系统范围的
/ actions / reload_cache

#7 楼

当遇到与您所描述的场景类似的场景时-想要将动词用作REST端点的一部分-我通常通过将动词转换为名词来解决该问题。
所以代替:
GET ${path}/cache/reload
我会这样做:
POST ${path}/cache/reload-request
这将迫使您改变对行为的看法。现在,您应该考虑如何创建代表重新加载请求的新资源。由于HTTP请求通常是短暂的,因此可以创建一个很好的抽象,它允许您返回包含id和status的资源,并发送要在后台处理的实际操作。然后,调用方可以稍后通过以下操作检查请求是否已得到处理:
GET ${path}/cache/reload-request/{id}
,或者甚至通过执行以下操作来取消请求:
DEL ${path}/cache/reload-request/{id}
有时您的操作是如此快速而简单,只需返回一个空的200 OK就足够了。这告诉调用方您已经接受了执行操作的请求,并且已经对其进行了处理,而无需进一步调用以检查状态。

#8 楼


应该使用哪个HTTP动词来触发REST Web服务中的操作?您将如何在网站上实现它?

HTML只能本地描述GET和POST请求。这样我们就可以开始搜索了。

GET是否合适?要回答这个问题,我们需要考虑允许客户和中间组件制造GET的假设。 GET的语义是安全的



,因为对目标资源应用安全方法,客户端不会请求也不希望原始服务器上的任何状态更改。同样,合理使用安全方法不会对原始服务器造成任何伤害,财产损失或异常负担。


因此,其含义是客户和中间组件可以酌情酌情调用GET请求,以满足自己的关注。蜘蛛可以随意获取资源以更新其索引。缓存可以预取。在不可靠的网络上,丢失的消息可能会根据需要进行重试,以确保至少有一个响应。


将用于重新加载配置,缓存等。


如果要做的事情很昂贵,那么也许您不希望客户自行决定发出这些请求。另一方面,POST实际上不受限制-这大大减少了允许通用客户端进行的假设。您不会获得发出推测性POST请求的组件,因为这样做会出错-标准中的任何内容都没有问题。
PUT更具体的语义;它们是否合适将取决于您的资源模型。

要记住的一个重要想法是HTTP方法属于文档域(请参阅Jim Webber的2011年演讲),您描述的效果可能不属于文档域,而是在更改文档时调用的副作用。 。在组织文档以完成工作的方式方面,这给了您很多自由。

#9 楼

那么PATCH呢?修改资源。将此与PUT进行对比;这是资源的完整表示。


PATCH不一定是幂等的,尽管可以。将此与PUT进行对比;这始终是幂等的。 “幂等”一词意味着任何数量的重复,相同的请求将使资源保持相同的状态。