5

是否有一种 RESTful 方法来确定 POST(或任何其他非幂等动词)是否会成功?在您基本上需要针对不同服务执行多个幂等请求的情况下,这似乎很有用,其中任何一个都可能失败。如果这些请求可以在“事务”中完成(即支持回滚)会很好,但由于这是不可能的,另一种方法是在实际执行之前检查每个请求是否会成功。

例如,假设我正在构建一个电子商务系统,允许人们购买印有自定义文本的 T 恤,并且该系统需要集成两种不同的服务:T 恤打印服务和支付服务。它们中的每一个都有一个 RESTful API,任何一个都可能失败。(例如,印刷公司可能会拒绝在 T 恤上打印某些文字,如果信用卡过期,银行可能会抱怨。)有没有办法推测性地执行这两个请求,所以我的系统只会继续如果这两个请求看起来都有效?

如果不是,这个问题可以用不同的方式解决吗?POST通过with创建资源status = pending,并将其更改为status = complete是否所有请求都成功?(DELETE更棘手...)

4

2 回答 2

2

HTTP 为您的场景定义了 202 状态代码:

202 接受

请求已被接受处理,但处理尚未完成。该请求最终可能会或可能不会被执行,因为在实际进行处理时它可能会被禁止。无法从诸如此类的异步操作中重新发送状态代码。

202 响应是故意不置可否的。它的目的是允许服务器接受对其他进程的请求(可能是一个每天只运行一次的面向批处理的进程),而不需要用户代理与服务器的连接持续到进程完成。与此响应一起返回的实体应该包括请求当前状态的指示以及指向状态监视器的指针或用户可以期望何时完成请求的一些估计。

来源:HTTP 1.1 状态码定义

这与 201 Created 类似,只是您表示请求尚未完成且实体尚未创建。您的响应将包含代表“订单请求”的资源的 URL,因此客户可以通过此 URL 检查订单的状态。


更直接地回答您的问题:在您提出请求之前,无法“测试”请求是否会成功,因为您要求的是千里眼。

当您将来尝试提出请求时,无法预见可能发生的技术问题的范围。网络可能不可用,服务器可能无法访问它的数据库或它所依赖的外部系统,可能会断电并且服务器处于离线状态,流浪的中微子可能会进入你的记忆并撞到 0为 1 导致灾难性内核故障。

为了使用远程服务,您需要将任何请求的可能失败与任何其他进程隔离开来。

对于您的具体问题,如果服务没有交易安全性,您就不能在其中烘烤任何东西,您必须以更真实的方式处理这个问题。我想到了几个选项:

  1. 让 T 恤公司给你一个“测试”机制,这样你就可以看到他们是否会在没有实际下达的情况下处理任何给定的订单。与他们下订单可能是一个两阶段操作,您在第一阶段构建订单(此时他们验证其创建),然后您随后要求处理订单(在您付款后成功地)。

  2. 先用信用卡付款,然后将您的订单转为“已付款”状态。然后尝试使用 T-Shirt 服务作为异步流程完成订单。如果履行失败并且您可以确定客户试图打印公司不准备生产的东西,您将不得不联系他们以更改他们的订单或退款。

大多数组织将采用第二种方法,因为它技术简单并且降低了业务风险。它还有一个好处是能够应付不可用的 T-Shirt 服务;异步过程只是等待服务可用并在那时完成订单。

于 2012-04-17T17:04:25.337 回答
1

确切地。这可以按照你在最后一句话中的建议来完成。这个想法是分离代表“订单接受”的“持续请求”的资源创建(除非网络故障,否则将始终有效),这可以稍后决定。由于 POST 返回“位置”标头,因此您可以随时检索请求的“状态”。

在某些时候,它可能会被接受或拒绝。这可能是瞬时的,也可能需要一些时间,因此您必须设计具有这些限制的服务(即允许客户检查他/她的订单是否被接受,或运行某种每小时/每日服务来收集接受的请求) .

于 2012-04-17T16:39:17.583 回答