我正在维护一个充满RPC样式*Web服务的遗留应用程序.例如,我们有以下服务用于从系统创建和删除用户:
https://example.com/createUser
https://example.com/deleteUser
客户端通过HTTP POST提交XML数据来调用这些服务.XML请求包含服务器处理请求所需的所有信息(即认证信息,用户信息).然后,服务器使用包含客户端应该知道的任何信息的XML文档进行响应(例如,成功/失败标志和描述).
我感兴趣的是将这些RPC样式服务切换到更RESTful架构的好处是什么.据我所读,这意味着以下内容:
要创建用户,客户端仍然需要通过HTTP POST提交XML数据(或PUT,具体取决于他们是否知道最终URL以及他们是否知道用户资源的所有必要信息).但是,身份验证信息将使用基本身份验证在HTTP标头中传递.
要删除用户,客户端会向https://example.com/users/ {user id} 发出HTTP DELETE调用.同样,身份验证信息将在HTTP标头中传递,而不是在请求正文中传递.事实上,据我所知,不应该有任何请求机构.
服务器应该尝试通过HTTP状态代码/状态描述尽可能多地指示,而不是在XML文档中指示成功/失败信息.
现在据我所知,将这些服务更改为更RESTful架构的主要好处是:
我们将利用HTTP提供的更多功能,特别是在身份验证方面.
URL更合乎逻辑,特别是如果我们需要开始在"用户"级别下公开资源(例如https://example.com/users/ {user id}/stuff).
它更符合Web的本机架构.
我错过了什么吗?我觉得使用RESTful架构会有更多好处.
*请注意,当我说"RPC样式"时,我并不是指XML-RPC或SOAP等标准化格式.
从实际和务实的角度来看,如果不了解您的应用程序,转换为REST将无法获得任何好处,特别是考虑到潜在的开发工作.
你有庞大的客户群吗?你有很多服务器吗?
REST的一个关键属性(但不是唯一的,甚至是必需的,但是......)是如何利用HTTP缓存的.
你在做任何缓存吗?这对你来说很重要吗?它适用于公共互联网上的大型系统.
如果您没有使用缓存,并且您认为它不会对您有太大帮助(即您没有很多客户端,您的服务器不会超级饱和,您的内容根本不适合,等等. ),然后REST可能甚至不值得追求,因为其他好处比缓存更不明显.
如果你只是通过HTTP发布POX(Plain Ol XML)(或JSON),并且这对你很有用,那我就不用担心了.
HTTP有其他好处,当然还有它的媒体类型,内容协商,缓存和位置标题等.但是,严肃地说,如果你没有看到用你的API做很多事情,请不要打扰.
如果缓存WOULD可以帮助你,那么它的价值就会越来越多地完全包含在HTTP协议和堆栈中,但没有理由为此进入REST架构.HTTP上的缓存POX也不是REST.它...通过HTTP POX.
这就是所有SOAP和XML-RPC都是...... POX over HTTP,只是SOAP XML带来了几个非常厚的标准......
如果您是一个拥有10年计划的庞大服务组织,那么您可能希望将迁移到全船REST架构,因为它是世界上真正的地方 - 长期的大型系统.
但这是一种真正的重新设计努力.
附加物:
REST试图解决的问题之一是系统的耦合.
RPC系统往往具有很强的耦合性.
因此,随着系统的发展,这种耦合成为系统发展的拖累.
考虑MS Windows和Linux的两个极端.微软花费大量时间尝试使MS Windows向后兼容,以便与传统(甚至是错误的)软件协同工作.这花费了他们的时间和金钱.
相比之下,Linux内核更加傲慢.当谈到内核时,他们对后向兼容性没有任何承诺.Linux因其破坏驱动程序以及从发布版本到发布版本而闻名.他们的主要优点是他们首先不承诺任何事情,所以当事情发生时不要感到沮丧.
这使得Linux内核人员更具创造性,并且移动得更快,因为他们可以随时随地进行折腾和更改.它还可以让团队更小.
现在考虑一个小型的RPC服务系统.由于它们是隐式紧密绑定的(与RPC的性质一样),当中央服务发生变化时,这种变化将会波及所有客户端.
如果这些客户很少,特别是如果他们在您的控制之下(当您开发整个系统而不是组件时),那么变化的程度不一定是痛苦和破坏性的.
但是你可以看到,如果你有数以千计的客户端和/或客户端,你不能控制对规范的实现,那么对核心服务进行更改可能会产生巨大的影响.哎呀,我已经发送了人员源代码,他们仍然弄错了.
REST有助于通过利用标准媒体类型(即不是某天你在白板上投放的某些XML),HTTP协议(你不需要HTTP来拥有REST拱门,但今天就是这样)和HATEOS来解耦系统.
粗略地说,HATEOS客户对事情的去向并不做任何假设.客户端会解析结果,以获取指向其正在执行的流程中的后续步骤的链接.
经典的例子是你(客户)购物亚马逊.所有你知道的是点击"结帐"按钮,但你不知道要去哪个网址.该URL可以固定不变,它可以每秒更改一次,它甚至可以导致重定向您的内容.你不知道,也不关心.这是服务器的特权.
因此,作为客户,您知道如何"点击结账"(即遵循最近有效负载中标记为"结账"的链接),但除此之外您还不太了解.值得注意的是,您的应用程序中没有硬编码的"http://amazon.com/checkout".
没有详细说明如何使用这些概念减少耦合,在这个阶段只需接受它们,并通过减少耦合,您作为服务提供商有一个更容易的机制来扩展,添加和更改服务作为服务消费者,你可以将您的系统集中在您特别感兴趣的服务方面,即使您背后的某些基础细节发生变化.再次考虑亚马逊多年来的变化,但至少我们都知道Checkout按钮的位置.
但是写这样的服务,并创建这样的客户,真的是相当多的工作.一些机制是"容易的",因为"我们一直这样做"(例如,提供HTML响应,谁不这样做?).但是,与媒体类型合作的范围更广,促进变革和发展,并使您的服务和客户对此环境更加强大和友好.这一切都需要工作,因为没有立即实现的好处.
"为什么我们为一项永不改变的服务做这一切?"
"因为从来没有比你想象的更早到来."
网络应用程序(如亚马逊)以RESTy方式取得成功,因为他们的客户恰好是人类,而且(大多数情况下)变得非常适应.但是,如果你曾经在一个热门网站上移动某个核心功能的按钮,你的收件箱会让你知道一些人真正的适应性.在机器级别执行此操作更加困难.
记住,这与"如果你不需要它就不构建它"形成鲜明对比"敏捷"我们可以稍后添加它"心态.
这就是为什么REST更适合具有长期前景的大型系统.它比战术更具战略性.它不仅仅是通过套接字推送位来获得结果.
希望有所帮助.