对资源执行过程和执行状态转换之间的区别是什么



我是web开发的新手,我正在尝试理解REST;程序";以及";状态转换";。指出REST是基于";"状态转换";,但它并没有描绘出两者之间的区别。

这让我想知道两者之间有什么区别?为什么转换资源状态的操作不能被视为过程?毕竟,"过程"听起来像是一个足够通用的术语,它还包含了一个可以转换资源状态的操作。

那么,对资源执行过程和执行状态转换之间有什么区别呢?还是仅仅是语义问题?

我也试着寻找答案,但似乎找不到任何能说明这一点的东西。

TL;DR

  • RPC专注于发送包含预定义格式的方法名称和参数的有效负载。客户端通过共享接口(Skeletton类、WSDL或其他接口定义语言(IDL))与服务器紧密耦合
  • REST专注于将客户端与服务器解耦,并引入间接性,如支持多种不同的媒体类型来整理资源状态,以及HATEOAS总结的整个交互概念,其中超文本控件用于通过服务器端的域应用程序协议/状态机来驱动应用程序状态。响应通常包含半结构化数据,这些数据通常不适合简单的CRUD应用程序,它们遵循相应的媒体类型定义(即HTML规范)的定义。如果愿意,资源的状态将转换为符合媒体类型定义中规则的表示格式,并传输到远程端

在网络编程中,远程过程调用(RPC)风格的调用,即经常在RMI、Corba、SOAP或类似框架中使用的调用,通常会发送一个应该在服务器上调用的方法名称以及为方法提供的参数。然后将返回值整理成相应的响应并发送回调用方。客户端可以调用的内容通常是通过外部内容公开的,例如skeletton类、WSDL或其他形式的契约等等。到目前为止,一切都很简单。这就是大多数网络内容的工作原理。然而,这里的缺点是客户端与公开的接口(skeletton类、WSDL、外部文档)紧密耦合,并且由于随着时间的推移而发生的变化,在这些接口中无法充分描述,因此在互联网计算中会出现许多问题。

如果你仔细观察一下网络几十年来的工作方式,变化是它固有的一部分。你的浏览器只会显示它所拥有的资源(网页)的最新状态。它可能是从缓存中或从它要求的服务器中获取的。如果其缓存中可用的版本早于预定义的阈值,它将忽略缓存的值并请求新版本。如果自上一版本以来发生了更新,则会自动为您的浏览器提供新版本。Fielding当时正在研究HTTP1.0和1.1规范,他分析了Web上的交互是如何发生的,并将他的发现推广到REST架构设计中。因此,如果您愿意的话,REST只是应用程序的Web冲浪

不幸的是,大多数爱好者和专业人士还不了解REST的真正含义,而且有太多关于REST的虚假信息,即使在Stackoverflow,大多数人似乎也不在乎,解释REST真实本质的帖子被否决,错误信息被否决。

那么,REST与典型的类似RPC的方法调用有什么不同呢?

首先,REST依赖于一组统一的接口,这些接口对于该体系结构中的每个参与者都是相同的。这些就是HTTP作为传输层和资源的命名方案(URI),以便每个人都按照这些固定的原则行事。这有助于减少在传统网络编程中常见的互操作性问题。

接下来,它依赖于一个基本原则:服务器教会客户端他们需要知道的东西。但是服务器如何知道客户端需要知道什么呢?正如Jim Webber所指出的,应用程序的设计者开发了一个状态机(或域应用程序协议),客户端将执行该协议。想象一下你最喜欢的网上商店的结账系统。在某一点上,它会向你展示你的巨魔中的项目,并为你提供进入下一个"巨魔"的选择;页面";在那里你可以输入发货地址,在进一步通过状态机时,你将被要求提供你的付款选项等等;谢谢你"页面,总结您的订单。在引擎盖下,您刚刚完成了他们关于如何下订单的协议,并使用应用程序控件进一步通过他们的状态机推进您的客户端。因此,您获得了一些用于完成任务的Web表单和链接。本质上,这就是超文本作为应用程序状态(或简称HATEOAS)引擎的全部内容。

在Web上,HTML表单用于向客户端传授资源支持哪些属性,哪些属性是可编辑的,等等。除此之外,它还向客户端传授将输入数据发送到的实际URI、到utilze的HTTP操作,以及将请求封送到的媒体类型(大多是隐式给定的)。也就是说,一个普通的HTML表单将使用application/x-www-form-urlencoded作为其默认媒体类型来将数据发送到服务器。因此,输入名字和姓氏的完整HTTP请求可能看起来像这样:

POST /path/to/resource HTTP/1.1
Host: acme.org
Connection: close
Accept: */*
User-Agent: ...
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
firstName=Roman&lastName=Vottner

如果表单所针对的媒体类型支持相同的数据,则可以使用不同的表示格式发送该数据。不幸的是,HTML不支持那么多。

服务器提供的链接通常应该由所谓的链接关系名称注释(或附带),该名称将当前资源与给定的URI联系起来。如果你愿意,它们是主体(当前页面)、谓词(链接关系名称)和对象(链接目标资源)三元组中的谓词。当然,这样的名称应该是标准化的,或者至少遵循Web链接扩展机制。URI本身是不透明的,这意味着它们本身不提供意义,因此根本不应该被解析和分析。一个常见的错误经常出现在所谓的";REST API";它们具有类型化的资源,即用户资源或汽车资源,这些资源可以在客户端编组到编程语言特定对象(即User类的Java对象等),这在传统RPC系统编程中非常常见。然而,在REST架构中,表示格式通常是半结构化数据,即定义控制输入或元素的语法与实际数据的混合。因此,像许多CRUD应用程序所做的那样,从DB条目到模型对象再到资源本身的直接映射是不可能的。

为什么一开始就这么做?

如果你比较传统的网络编程,客户端通常只能与那台服务器一起工作,如果服务器上的某些东西发生了变化,客户端可能会受到影响,从而停止工作。这两者之间有着紧密的联系。REST体系结构引入了两种间接方法,即使用链接关系而不是试图分析有意义的URI,以及使用多种可能的媒体类型而不是依赖于指定的版本格式,这有助于将客户端与服务器解耦。也就是说,在交换消息时,客户端和服务器都耦合到媒体类型。通过内容类型协商,客户端只需"告知"服务器其功能,服务器应生成客户端可以处理的响应。REST不专注于一种消息格式,而是拥有几乎无限的消息格式的自由,只要客户端和服务器都支持这些格式。对等体支持的媒体类型越多,就越有可能与该网络中的其他对等体进行交互。

我上面提到的所有这些点都导致了客户端和服务器的严格解耦,这允许后者自由发展,而不必担心引入的更改会破坏客户端,因为传输协议和命名方案都没有改变,引入的更改仍在媒体类型定义的范围内。因此,该网络中表现良好的对等体将能够自动接收变化。如果您开发的应用程序能够经受住时间的考验,并且在未来几年仍能为服务器客户端提供服务,那么这一点尤其方便。

如果你不需要这样的属性,那么不成为";RESTful";根本不需要调用这样的服务/API REST。此外,与典型的RPC风格的交互相比,开发REST无疑需要更多的开销。

最新更新