确定什么是RESTFull应用程序和/或api并不总是很容易,因为对于REpresentational State Transfer架构风格的含义和范围存在一种误解。
最初,我在形容词" REpresentational"首字母缩略词REST,简称。这是因为"代表性国家"听起来不太好......
此外,我对这种建筑风格的作者blog post给罗伊菲尔丁留下了深刻的印象,他对基于http动词的api经常出现的误解感到非常失望,特别是他抱怨关于这些api的客户端和服务器之间关于它们的名称和数据结构的耦合。
博客文章参考:http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven
我想尝试仅提供有关REST arch的理论解释。风格,我想知道其他观点。
答案 0 :(得分:7)
第一部分
我的主要目标是将注意力集中在名称"代表性国家转移"的原因上。
我认为关于REST的大多数误解都在形容词" representational"之下。 大多数人认为"代表性" word与资源状态有关,因此构建了专注于对象结构的应用程序,以便与调用客户端进行通信/转移......但我认为重点是" transfer",它是转移到& #34;具有代表性",因此重要的设计应用程序(或api)使用" Representational"他们依赖的REST网络系统的能力,以支持客户端 - 服务器组件之间的传输。
要弄清楚关于REST架构风格的关注的整个问题,需要理解作者Roy Fielding打算在他的论文中提出一套基于hipertext或hipermedia构建架构的架构原则。范式,所以这个范例是理解这个重要主题的核心关键。
在组织由Roy Fielding提出的客户端 - 服务器应用程序架构的风格背后,我认为现代客户端 - 服务器应用程序有一个特定的概念,它由一种控制应用程序状态转换的引擎组成。 ,其状态可能是可扩展的无限。
在这个愿景中,Ipertext \ Ipermedia是Fielding提出的整个建筑风格的中心,允许这种范式工作的关键概念是代表性(状态)转移"。
所以我们可以理解为什么这个词代表"指的是关于"转移"的概念,而不是关于" state"的概念。因为转移是代表性的(代表性类型),这意味着是管理"转移"的系统。并且依赖于客户端 - 服务器交互,给出关于表示的一些标准指示,即媒体类型概念(或REST的Web实现中的MIME),也就是说,在我看来,主要原因是姓名"代表性国家转移"。
因此,在设计Restfull应用程序时,首先要设计一个基于组件网络的体系结构,每个组件都与客户端 - 服务器分层体系结构模型中的其他组件通信,并向每个组件发送其状态的表示。
因此,前端,这个架构的第一个客户端,通过其状态转换,显示由组件或组件发出的状态的表示,它称为在统一的一致接口上支持而不是&# 34;私人" API。
在作者的脑海中,这种类型的应用程序可能可扩展到无限状态,因为它的状态不依赖于私有api,而是依赖于由univoque标识符系统(作为URI)共享的这个架构中的所有代理,在一些动词上用于管理其状态的转换以及商定的共享代表性转移系统,或者加上。
这种转换以其表示通过构成" public"的动词与被叫服务器组件的通信而告终。 api,它应该属于客户端 - 服务器组件使用的无状态通信协议。
通过这种方式,这种客户端 - 服务器组件交互包括基于无状态协议的使用,交换(传输,传递)组件状态的标准化表示(媒体类型)。
允许所有这些架构可能扩展到无限的核心概念是组件的资源结构和名称与其客户端识别和表示(代表性传输)的分离。 < / p>
第二部分
有关mediatype和RESTful应用程序构建的更多详细信息
我认为Fielding最初的直觉是,在分布式应用程序架构中允许客户端和服务器组件之间完全解耦并且无限可扩展的关键特性是开放和不断发展的标准表示集的定义,因此,这些组件能够交换这些表示,并在客户的情况下解释它们。
这就是为什么&#34;代表性转移&#34;!
即,基于标准化的rappresentations转移。 相反,&#34;州&#34;正是以标准方式表示的内容,因为任何支持REST原则的客户端组件都能理解它,并允许表示本身成为状态转换的引擎,其中包含其媒体类型表示还包括标准信息处理,它们应该引用它们与客户端 - 服务器通信协议相关的一小组标准动词。
因此,要构建遵循标准REST并因此遵循RESTful的应用程序(或从REST角度来看的连接器),意味着:
为自己的资源设计uri;
使这些uri始终可用于发送给客户的表示;
专注于设计最合适的媒体类型表示,以支持自己的应用程序流,因此相同的状态转换。
这意味着支持任何类型设备上的任何类型的媒体,并且还支持任何类型的交互系统或过渡状态(例如,不仅是用户的自动化系统)
答案 1 :(得分:4)
虽然我觉得这篇文章显然更适合programmers,因为这是一般性的概念讨论,我会试着尝试一下。
对我来说,REST是将当前包含在某个资源中的状态或数据从服务器传输到客户端,反之亦然。客户端通过在资源上调用底层通信协议提供的某些操作来初始化此传输。表示方面现在是状态/数据的返回样式/风格/类型。如果客户端请求类似Accept: "application/hal+json", "application/json", "text/html"
的内容,则直接向服务器请求以三种格式中的任何一种格式表示状态(优先于前导格式),服务器可以根据其功能决定哪一种格式为返回。某些权重偏好也可以指定,以提高服务器返回此媒体类型的可能性,而不是其他更普遍的。
REST的简单实际上很难在现实中实现,稍后会更多。除了一些architectural constraints Roy Fielding到位之外,给定的链接还包括一些必须遵守的事项列表,以便调用已在以下列表中汇总的服务或API RESTful:
API应遵守并且不违反基础协议。在大多数情况下,通过HTTP使用Altough REST,它不限于此协议。
通过媒体类型强烈关注资源及其展示。
客户不应对API中的可用资源或其返回状态("typed" resource)有初步了解或假设,而是通过已发出的请求和分析的响应动态学习它们。这使服务器有机会轻松移动arround或重命名资源,而不会破坏客户端实现。
特别是Roy Fielding给出的最后一条规则经常违反,不让客户端发现资源,因为端点被明确地编码到客户端/应用程序中。返回的类型也经常被预先分配。这会在StackOverflow中产生大量与URI设计相关的问题,因为URI需要携带语义以便开发人员将它们放入客户端。
但媒体类型通常仅限于支持application/json
或application/xml
,但它们不会对实际内容进行任何语义操作。 XML特别设计为可扩展的,因此名称中的X.已经存在大量基于XML的特殊类型,严格的框架通常只返回application/xml
,这会给客户带来负担,知道响应在语义上意味着什么。
普通XML
和JSON
但不传达实际内容的任何语义或定义支持客户理解的规则。它们只是描述客户端可以用来识别响应包含哪些元素以及它们包含哪些数据的语法,仅此而已。
通常建议Atom / RSS和Json-HAL至少增强HATEOAS要求,因为它们提供到其他资源的链接,因此帮助客户在语义上掌握某个字符串必须被解释为它可以采取行动的进一步资源根据。但是,客户仍然不知道它实际处理的数据。因此,应该开发特殊的媒体类型,支持客户理解数据的全部内容 - 并且它们对于相同的资源状态可能有不同的风格,即只提供资源状态的概述,而其他媒体类型可能包含全套数据。
在我看来,这导致菲尔丁发表以下声明:
REST API应该花费几乎所有的描述性工作来定义用于表示资源和驱动应用程序状态的媒体类型,或者为现有标准媒体定义扩展关系名称和/或启用超文本的标记类型。
REST尝试引入的东西是从客户端到特定API集的明显分离,就像Web浏览器没有耦合到特定的Web服务器。 Web浏览器能够呈现大量填充有图像或其他媒体类型的HTML页面而不会破坏。通过让客户从基本URL开始然后通过解释响应来探索新的可能性来实现解耦。因此,HATEOAS通过遵循服务器在先前请求上给出的链接来驱动客户端状态更改。因此,服务器端的更改不会阻止任何真正的RESTful客户端,因为它们只会使用从先前响应中学到的内容。期望资源X在路径Y处被放置并具有状态Z的客户端将高度确定地中断服务器更改。
对我来说,媒体类型是客户的知识库,并教她如何处理某种类型的文档。浏览器即将呈现HTM1页面,使其实际上对于人类可读。它还将使用JavaScript代码和已注册的事件动态更改表示。某些下载的字节可能会显示为图片,有些会被解释为视频,而其他类型可能会产生处理内容的某个对象(如某些视频播放器,Flash播放器或小程序)。
现在的现实问题是:如何编写任意客户端能够真正理解的媒体类型。任意地,我的意思是类似于自动化系统,它没有API或服务的基本知识,因此必须通过请求/响应来学习所有内容。由于状态及其表示可能有许多不同的风格,因此教导客户如何解释数据是一件困难的事情。数据的语义处理仍然是一个巨大的研究领域。自动化系统需要知道某些字符串具有某种语义,并且服务器返回的模板URI中的某些内容需要一个满足此语义的输入。
IANA可以找到或多或少知名的注册媒体类型列表。在可能的情况下,建议使用这些介质类型中的一种(如果适用),以避免再次重新发明轮子。但是,某些用例可能需要自定义格式,因此需要额外的开销(设计,实现并最终在IANA注册媒体类型可能需要一些时间)。
作为对这个缺点的反应,许多实现者试图走简单的路线并将知识放入客户端,然后客户端与API紧密耦合,并且不会轻易地对API本身的变化作出反应。对于我们这些人来说,掌握URI的意图是相当简单的,因此我们坚持使用干净的URI-API。用户有一定的预先假设(基于命名或一些文档)API能够做什么,因此将REST减少到marketing term。
像Fielding所说的那样,很多人都有误解,认为在HTTP上运行的API被认为是RESTful。此外,Richardson maturity model对此问题没有帮助,并且StackOverflow社区将与HTTP上的API相关的所有内容视为REST。