向需要确认的RESTful POST请求提供参数

6
我正在开发一个REST服务,其中我的服务器端操作以一种可能需要一些时间的方式操纵数据库,但是一旦操作开始,就无法恢复数据库(这是来自我们服务器上使用的系统的限制。我可能能够在以后的版本中更改它,但现在我们被这个限制所束缚)。 结果是,在允许操作运行之前,我需要一个带有警告的“确定/取消”对话框。

起初,我想把创建对话框的逻辑放在客户端上,但这似乎违反了HATEOAS(例如,如果我在服务器端更改框架,那么对话框将不再需要,但如果我的API保持不变,我将不想更改客户端)。 我的下一个解决方案是返回一个带有警告和链接到不同POST操作的ok的响应,但我不确定何时发送我的参数。我在第一个POST中发送参数吗?如果是这样,它们如何到达第二个POST(当然不能保持应用程序状态)?仅将参数发送到第二个POST并不是一个选项,因为只有HATEOAS才能确定是否需要第二个POST。
我在这里找到了一个类似的问题: REST, HTTP DELETE and parameters 但是它有两个问题:
  1. 它不能解决我们的问题(因为他只在第二次尝试时添加参数,但我需要从第一次开始就携带我的参数)。
  2. DELETE必须符合“统一接口”。 他确实提出了一个有效的观点,即并非所有客户端都需要确认,但将整个对话框放在UI中会让我回到我们的问题,即如果我改进了我的服务器端应用程序会发生什么。

我很乐意听听您对此事的想法。

P.S:这是我在stackoverflow.com上的第一篇帖子(经过多年使用它来查找在我之前提出的问题的答案),所以请原谅我如果问题的格式不太正确(当然,您可以纠正我)。


你可以生成一个令牌来“确认”或授权 DELETE 操作。例如,POST /confirmations 返回一个带有确认实体的 201 状态码。然后,该实体通过 HTTP 头部传递给 DELETE /users/1 - jchook
你可以先发出一个请求以获取令牌,当你在第二个请求中发送该令牌时,操作就会发生。 - The Fool
3个回答

1

您的服务器端操作在执行之前需要确认。按照我的理解,这意味着需要进行两个不同的调用,例如首先检查是否需要确认,然后再执行实际操作。

例如,您可以要求客户端首先进行GET请求以查看是否需要确认并检索要显示的消息,然后执行实际的POST操作。如果没有先进行GET请求,则POST可能会返回4xx(可能是412)错误。

但是,请记住,无论您做什么,都需要客户端的配合。即使服务器收到了GET请求,客户端可能会收到响应,但不显示确认并仍然执行POST,这不是您可以完全在服务器端解决的问题。


0

我不会修改DELETE的语义,就像链接文章中的一个解决方案(返回4xx以强制新请求)。如果DELETE无法正常工作,这会让大多数人感到惊讶,应尽可能避免出现惊喜。

我的第一个想法是,可以类似于HTML中的确认对话框来解决它。也就是将一些代码放入链接中,或者可能是一些标志来指示需要确认才能删除:

<a rel="something" onDelete="confirm" href="..."/>
<a rel="something" onDelete="showConfirmation()" href="..."/>

一开始看起来似乎没问题,但这真的是链接的属性吗?根据您对问题的描述,似乎您正在定义POST操作本身的某些能力是否存在。这个能力是可恢复性还是回滚性?因此,如果客户端需要检测操作的某些能力,可以使用以下方式进行OPTIONS请求:

OPTIONS /something/abc HTTP/1.1
...

200 OK
Allow: GET,HEAD,POST,OPTIONS,TRACE
...
<body describing confirmation dialogs, messages, etc>

基本上,您可以通过自定义表示形式来宣布OPTIONS的功能。规范明确允许此操作(https://www.rfc-editor.org/rfc/rfc7231#section-4.3.7):

生成对OPTIONS的成功响应的服务器应发送任何可能指示服务器实现的可选功能并适用于目标资源(例如Allow)的标头字段,包括未由此规范定义的潜在扩展。


0

对于关键操作,考虑要求一次性的服务器端生成的令牌。因此,客户端始终需要首先发出另一个非关键请求来获取令牌。只有使用该令牌才能进行关键调用。因此,在这种情况下,获取令牌是启动的行为,将令牌发送到关键端点是确认的行为。

所有操作所需的详细信息应与第一个请求一起发送,因此令牌仅确认特定的参数集。在第二个请求中,仅需要令牌,任何其他操作所需的参数必须已经被发送并编码或由令牌识别。

这样,客户端就不能意外地调用关键请求或使用另一个令牌来确认不相关的操作,而不是首先明确请求它,这在某种意义上是一种确认,因为单个“错误”不能导致意外的结果。

当然,客户端仍然可以决定在未提示用户的情况下执行两轮操作,但我们无法做太多事情。


我刚注意到jchook在上面的评论中说了同样的想法... - Bence Szalai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接