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