刚接触这个主题的读者会被关于你应该做什么的无休止的讨论以及相对缺乏经验教训所震惊。我认为 REST 优于 SOAP 的事实是从经验中学习的高级别的,但是我们一定是从那里取得进步的吧?现在是 2016 年。Roy 的论文是在 2000 年。我们开发了什么?它有趣吗?容易集成吗?支持?它会处理智能手机的兴起和不稳定的移动连接吗?
根据 ME 的说法,现实生活中的网络是不可靠的。请求超时。连接被重置。网络一次中断数小时或数天。火车与移动用户一起进入隧道。对于任何给定的请求(正如在所有讨论中偶尔承认的那样),请求可能在途中落入水中,或者响应可能在返回途中落入水中。在这种情况下,直接针对实质性资源发出 PUT、POST 和 DELETE 请求总是让我觉得有点野蛮和幼稚。
HTTP 没有做任何事情来确保请求-响应的可靠完成,这很好,因为这正是网络感知应用程序的工作。开发这样的应用程序,您可以跳过箍以使用 PUT 而不是 POST,然后如果检测到重复请求,则更多箍在服务器上给出某种错误。回到客户端,您必须跳过障碍来解释这些错误、重新获取、重新验证和重新发布。
或者您可以这样做:将您的不安全请求视为短暂的单用户资源(我们称它们为操作)。客户端通过对资源的空 POST 请求对实质性资源执行新的“操作”。POST 将仅用于此目的。一旦安全地拥有新生成的操作的 URI,客户端会将不安全的请求发送到操作 URI,而不是目标资源。解决操作和更新“真实”资源是您的 API 的正确工作,并且在这里与不可靠的网络分离。
服务器执行业务,返回响应并将其存储在约定的操作 URI中。如果出现任何问题,客户端会重复请求(自然行为!),如果服务器已经看到它,它会重复存储的响应并且不执行任何其他操作。
您将很快发现与 promise 的相似之处:我们在执行任何操作之前创建并返回结果的占位符。也像一个承诺,一个动作可以成功或失败一次,但它的结果可以重复获取。
最重要的是,我们为发送和接收应用程序提供了将唯一标识的操作与各自环境中的唯一性相关联的机会。我们可以开始要求并强制执行!客户负责任的行为:尽可能多地重复您的请求,但在您拥有现有请求的明确结果之前不要生成新的操作。
这样,许多棘手的问题就消失了。重复的插入请求不会创建重复,并且在我们拥有数据之前我们不会创建真正的资源。(数据库列可以保持不可为空)。重复的更新请求不会达到不兼容的状态,也不会覆盖后续的更改。无论出于何种原因(客户端崩溃、响应丢失等),客户端都可以(重新)获取并无缝处理原始确认。
连续的删除请求可以查看和处理原始确认,而不会遇到 404 错误。如果事情花费的时间比预期的要长,我们可以临时做出回应,并且我们有一个地方可以让客户检查最终结果。这种模式最好的部分是它的功夫(熊猫)属性。我们采取弱点,即客户在不理解响应时重复请求的倾向,并将其转化为优势:-)
在告诉我这不是 RESTful 之前,请考虑尊重 REST 原则的多种方式。客户端不构建 URL。API 保持可发现性,尽管在语义上有一些变化。HTTP 动词使用得当。如果您认为这是一个巨大的实施变化,我可以根据经验告诉您事实并非如此。
如果您认为要存储大量数据,让我们来谈谈容量:典型的更新确认只有千字节的一小部分。HTTP 当前给您一两分钟的时间来明确响应。即使您只存储一周的操作,客户也有足够的机会赶上。如果您的容量非常大,您可能需要一个专用的符合 acid 的键值存储或内存解决方案。