总说接口定义要遵守 RESTful,那么什么是REST呢,今天跟小编一起来了解一下这个规范吧~!
原文作者简介:
BRIAN SLETTEN是一个关注前沿技术的软件工程师,现居于加州奥本。他的职业生涯横跨了各个行业,包括零售、银行、网络游戏、国防、金融、酒店和医疗保健。他拥有威廉玛丽学院的计算机科学学士学位。BRIAN SLETTEN致力于Web架构、资源计算、社交网络、语义网、数据科学、三维图形、可视化、可伸缩系统、安全咨询等第二十世纪末和第二十一世纪早期的技术。
引言
表述性状态传递架构风格(Representational State Transfer)不是一项可购的技术,或者是一个在软件开发项目中可以添加的库。它是一种将信息提升为我们构建的架构的第一类元素的世界观。
我们用来描述“REST”系统的一些概念和术语参照了Roy Fielding博士的论文《基于网络的软件体系结构的架构风格与设计》(http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm)。尽管这是一篇学术论文,用词十分正式,但是它仍然保留了通俗易懂的特点,为实践提供了许多依据。
这些概念在我们称之为Web的实现中得到了很好的证明。倡导RESTful风格在本质上来说,就是鼓励组织在内部采用对外相同的原则。
基本概念
REST服务基于统一资源定位器(URL)。它能够将指定资源与接受或返回的资源分开。URL方案在 RFC1738 (https://tools.ietf.org/html/rfc1738)中被定义。
对于某虚构的图书馆,它可能拥有一个如下所示的RESTful风格的API:
http://fakelibrary.org/library
因此,被暴露的并不一定是某种服务,而是一种对用户来说有价值的信息资源。实际上,URL用作资源的句柄,可以对资源进行请求、更新或删除。
首先我们要发布和这个虚拟图书馆进行RESTful风格交互的方法。RESTful的返回类型可以是XML,JSON或者是某种其他的超媒体格式,比如Atom或者用户自定义的MIME类型。一般来说,我们要尽可能地复用现存的格式。但是,使用合理自定义的媒介的趋势正在不断增长。
用户可以使用一个超文本传输协议(HTTP)的GET方法来请求一个资源。比如说,在浏览器中输入一个URL并点击返回,选择书签,或者点击一个锚引用链接。
我们可以使用各种用户端的API或者工具来与RESTful式的API进行交互。如果使用命令行的curl工具,我们可以输入:
$ curl http://fakelibrary.org/library
在命令行上,返回的结果的形式是默认的。然而,我们并不想要这个形式的信息。所幸利用HTTP的机制,我们可以以不同的形式请求信息,可以在请求中指定一个“Accept”头,如果服务器支持该请求,那么服务器就会将它返回到客户端。根据下述格式再次使用curl:
$ curl –H "Accept:application/json"
http://fakelibrary.org/library
由于资源名与表单的分离,这种不同形式的信息请求方式是可行的。在REST中“R”指代的是“表示(representation)”而不是“资源(resource)”。在构建系统的时候要牢记这一点,我们要允许客户以他们想要的形式请求信息。
我们的虚拟图书馆中可能包含的URL:
http://fakelibrary.org/library - 有关图书馆的大致信息,以及查找特定书籍、DVD等的链接的基准。
http://fakelibrary.org/book - 图书的“信息空间”。从概念上讲,它是所有可能的图书的占位符。显然,如果它是一个确定的值,我们就不能返回所有的书籍,但它可能会返回通过类别、关键字搜索等方式发现的图书。
http://fakelibrary.org/book/category/1234 - 在书籍的信息空间里,我们可以想象以特定的类别(例如小说、儿童书籍、园艺等)来浏览它们。
http://fakelibrary.org/book/isbn/978-0596801687 - 指代某一个特定的书籍。它应该包括关于标题、作者、出版者、藏书量、余量等信息。
上述提到的URL对于用户来说可能是只读的,但是图书馆员可能会对这些资源进行操作。
举例来说,我们可以向图书的信息空间POST一个XML,来指代添加一本新的书籍。使用curl:
$ curl –u username:password -d @book.xml -H
"Content-type: text/xml" http://fakelibrary.org/book
此时,服务器可能会验证结果,创建与本书相关联的数据记录,并返回“成功创建新资源”的201响应代码。我们可以在响应头中找到新资源的URL。
每一个RESTful请求都包含了足够的状态来回应请求。这满足了服务器上的可见性与无状态性,实现了系统的收缩性,并确定了正在执行的请求。这有助于实现结果的缓存。在结果集中,服务器的地址和请求的状态组合在一起形成一个计算散列键(hash key):
http://fakelibrary.org + /book/isbn/978-0596801687
由于GET请求的特性,它允许客户端在必要情况下做出非常具体的请求。用户可以在本地缓存结果,服务器可以缓存在远程。另外,一些中间的体系结构也可以进行缓存。但是这并不意味着任何人都可以操作资源,可以设置一个保护模式,在用户对资源进行操作之前,进行身份验证。
关于SOAP
SOAP和REST经常被用于比较。许多人误以为它们是等价的。实际上,他们是两个不同的东西。这种错误认识主要源于人们认为“REST”是通过URL调用的Web服务。而事实上,REST是一种通过对信息的解耦来管理系统的方法。利用REST,我们可以实现:
高性能
可收缩性
通用性
简化性
可修改性
可扩展性
这并不是说基于SOAP的系统不能拥有以上特性。但是,SOAP最适合的使用场景是,由于技术、组织或程序上的复杂性,导致请求的生命周期不能维持在单个事务范围内的情况。
Richardson成熟度模型
Leonard Richardson引入了成熟度模型,用于在一定程度上阐明SOAP与REST之间的区别,并且提供了一个区分不同类型系统的框架。我们可以把这种分类看作测定一个系统所包含不同的Web技术的程度:信息资源、HTTP作为应用协议、超媒体作为控制媒介。
将其称为“成熟模型”似乎意味着我们应该只在最成熟的级别上构建系统。其实不然,LEVEL2是有一定价值的,并且转换到LEVEL3通常只需要采用一种新的MIME类型。即使提高ADOPTION会增加价值,但是从LEVEL0到LEVEL3的转换仍然困难许多。
构建RESTful的流程是,首先确定想公开的信息资源,采用HTTP作为处理这些信息资源的应用程序协议,包括对内容协商的支持。然后,采用基于超媒体的MIME类型,你将体会到使用REST的所有优点。
RESTful中的动作词汇
一般来说,初学者们对RESTful中经常出现的几个动作词汇感到十分困惑。这种看似绝对的约束,实际上旨在通过非特定的方式来鼓励可预测的行为。通过明确地定义这些行为,用户可以在面对网络中断和故障时自主地做出决定。以下是RESTful系统中4个主要的HTTP动作(有时也被叫做方法):
GET
Web应用中最常见的动作,GET请求将指定的资源从服务器传输到客户端。用户不需要对他请求的资源有任何了解。它返回的是用元数据标记的字节码,指示客户端应如何解释它。在
Web端,这通常是“文本/html”或“应用/xhtml+xml”。正如我们上面提到的,在使用内容协商的情况下,只要服务器允许,用户就可以获得所有请求的资源。
GET请求最关键的特征之一是他不能修改任何服务器上的数据。它是一个绝对安全的请求。这也是初学REST的人常犯的错之一。在上文提及的成熟度模型LEVEL1的系统中,我们经常可以看到这样的URL:
http://example.com/res/action=update?data=1234
千万不要这样做!这是完全不符合RESTful的生态特性的。GET请求必须是安全的(不能修改任何数据)。
此外,GET请求也必须是幂等的。这意味着多次执行统一个请求总是得到相同的结果。这是在基于网络的分布式系统中的一个非常重要的特性。如果客户端在发出GET请求时被中断,根据幂等性,该请求应该被再次发出。这是非常关键的一点,因为在一个设计良好的系统中,什么用户从哪个应用发送请求是无关紧要的,应用总会做出特定的响应。但是我们越多地推进这种非特定于应用程序的行为,系统就越有弹性且易于维护。
POST
如果仅从动词解释的角度来看,POST和PUT确实没有太大的差别,因为他们都可以表示创建或者更新资源。然而在RESTful系统中,他们是完全不同的。
在用户无法确定他想创建的资源的属性时,我们需要使用POST。例如,当我们下订单,或者提交表单时,我们无法预测服务器会如何命名这些资源。这也是我们需要向服务器POST一个资源的指代(representation)的原因。服务器会对用户的输入进行接受、验证等操作。如果这些操作都成功执行,那么服务器将会返回一个HTTP201响应。响应的头中包含了新创建的资源的位置信息。
需要注意的是,有些人把POST看作一个对话式的GET请求。与一般情况下返回201状态码不同的是,他们会设置服务器返回一个200状态码,并将所创建的资源放入内容体。这看似是一个避免第二次请求的“捷径”。但是,它将POST请求和GET请求合并在了一起,使资源的缓存变得复杂化。因此,请尽量避免以牺牲大局为代价去走这样的“捷径”。虽然短期看起来很方便,但这些“捷径”会在将来给你带来很大的麻烦。
POST的另外一个主要的用法是增补一个资源。这是一种增量编辑或者部分更新,而不是增加一个完整的新资源。举例来说,对一个已知资源的POST部分更新可以是,添加一个送货地址或者是修改购物车中商品的数量。
由于这种潜在的部分更新,POST不是一个安全、幂等的请求。
POST还被用在提交查询上。查询内容或者URL编码的表单值会被提交给服务器来解释查询。因为查询中没有关联标识,因此直接从这样的POST请求返回的结果是合理的。
注意:可以考虑将一个查询转换成信息资源。一旦这样的查询被定义到了信息空间,我们就可以使用GET请求来获取信息资源。同时我们也可以将这样的链接分享给其他人。
PUT
因为HTML表单目前暂不支持PUT,许多开发人员在很大程度上忽略了这个请求。然而,它是RESTful系统中不可或缺的一环。用户可以向已知URL发出PUT请求来完成对资源的重写。不同于POST对资源的更新,PUT请求是幂等的。如果一个用户在发送PUT请求时被中断,由于幂等性,用户完全可以重新提交一次该请求。
如果用户可以预测资源的在服务器上的标识,那么PUT也可以用来新建资源。这种情况并不常见(原因参照上一节在POST中的讨论),但是如果用户端控制着服务器端的信息空间,那么这样做也是合理的。
DELETE
在公共的Web上,DELETE没有被大量的使用。但是他依然是RESTful生态系统中重要的一环。
DELETE是幂等的。如果一个DELETE请求被网络的故障打断,用户可以重新提交一次请求。不管第一次请求是否成功删除了指定资源,用户得到的响应都应该是204(内容不存在)。对于被删除的资源或者从未存在的资源来说,追踪他们可能需要一些额外的处理。出于安全考虑,对于已删除或者从未存在的资源,我们应该返回404状态码,从而不泄漏任何信息。
除了上文提到的4个常用的动作,还有另外三个不常用的动作,他们同样重要。
HEAD
HEAD用于请求一个资源,但实际并不将它取回。这是客户端检查资源是否存在,并可能发现元数据的一种方式。
OPTIONS
OPTIONS可以通过询问其他可用的请求,来向服务器询问某个资源。
PATCH
PATCH是一种最新的HTTP方法,它只是在2010年初正式作为HTTP的一部分。它标准化的表达了对资源的部分更新。正如上文所说,POST可以在任何场所被使用,然而,没有一个明确的规范来限制什么时候要将它用于部分更新。
标准格式的PATCH请求允许在交互中更明确地表示请求的意图。IETF(国际互联网工程任务组)提出了一些RFC(请求评议)来修补XML和JSON.
如果用户提出了一个请求头为If-Match的PATCH请求,那么该请求很有可能实现幂等,这意味着,该请求被意外中断以后是可以重启的。因为一旦该请求在第一次被成功执行,那么它的If-Match请求头就会与新的状态不同。如果他们相同,则代表第一次的请求未被成功执行,新的Patch请求将会被合理执行。
HTTP响应码
HTTP的响应码提供了关于用户和服务器之间请求的详细诊断信息。许多人仅仅熟悉几个响应码,比如200,403,404和500。事实上,实用的响应码还有很多很多。下表列出了一些在RESTful环境下,开发者必须了解的响应码。
REST资源
参考论文
Fielding博士的论文。《基于网络的软件体系结构的架构风格与设计》(http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm)
一.RFC
定义REST技术规范由互联网工程任务组(IETF)请求注释(RFC)流程驱动。该规格给出了各个版本的版本号,并随着时间的推移将现有的旧版本更新成新版本。目前,这是最新的请求注释(RFC)。
URI
RFC3986包含了URI结构的命名方案。URI可以包括其他命名方案的编码,如网站地址、命名空间、子方案等等。
链接:[ietf.org/rfc/rfc3986.txt](ietf.org/rfc/rfc3986.txt)
URL
统一资源定位器(URL)是URI的一种形式。URL被嵌入了解析和定位资源(通常是访问方案和地址)的信息。
链接: [ietf.org/rfc/rfc1738.txt](ietf.org/rfc/rfc1738.txt)
IRI
国际化资源标识符(IRI)在概念上是以Unicode格式编码的URI,以支持来自世界各地的语言的字符。IETF选择创建一个新的标准,而不是改变URI方案本身,这样可以在这两种方法之间建立一个明确区分,同时不破坏现有的系统。IRI的支持者是故意为之的。因为存在一些使IRI和URI相互转化的映射方案。
链接:[ietf.org/rfc/rfc3987.txt](ietf.org/rfc/rfc3987.txt)
HTTP
超文本传输协议(HTTP)在1.1版本定义了一个应用程序协议,用于处理超媒体格式表示的信息资源。虽然它是一个应用程序级协议,但它通常不是特定于应用程序的,因此重要的架构效益应运而生。大多数人认为HTTP和超文本标记语言(HTML)就是“Web”,但是HTTP在开发面向非文档的系统时也很有益处。
链接:[ietf.org/rfc/rfc2616.txt](ietf.org/rfc/rfc2616.txt)
PATCH FORMATS
JavaScript Object Notation (JSON) Patch:
链接: [ietf.org/rfc/rfc6902.txt](ietf.org/rfc/rfc6902.txt)
XML Patch Site:
链接: [ietf.org/rfc/rfc7351.txt](ietf.org/rfc/rfc7351.txt)
描述语言
人们热衷于用语言来描述API,以便更容易地为客户机和服务器编写文档,甚至可能生成框架。下面描述一些较流行或有趣的语言:
RAML
一种用于描述面向LEVEL2的API的YAML/JSON语言。它包括对可重用模式的支持,这个特性有助于标准化API的功能设计。
链接: [raml.org](raml.org)
SWAGGER
另一种用于描述面向LEVEL2的API的YAML/JSON语言。它包括代码生成器、编辑器、API文档的可视化以及与其他服务集成的能力。它是开放API战略的基础。
链接: [swagger.io](swagger.io) 和 [swagger.io](swagger.io)
APIARY.IO
一个协作的托管站点,支持基于Markdown的API文档,围绕设计过程进行的交互,以及对模拟托管实施的支持,以便在实施之前轻松测试API。
链接: [apiary.io](apiary.io)
HYDRA-CG
它是一种超媒体描述语言。它通过某些标准(比如json-ld),使得自己对数据链接的支持、与其他数据源的交互更为容易。
链接: [hydra-cg.com](hydra-cg.com)
二.实际应用
有几个库和框架可用于构建生成和使用REST系统的系统。
现在有许多库和框架可构建使用RESTful的系统。虽然任何Web服务器都可以配置REST API,但使用这些框架和库更为方便。下面是一些主要环境的概述:
JAX-RS:
该规范增加了JEE对REST的支持。
链接: [jax-rs-spec.java.net](jax-rs-spec.java.net)
RESTLET:
Restlet API是在RESTful系统上建立Java API的先期尝试之一。他的重点在于建立一套在用户端和服务器端功能对等的既简明而又功能强大的API。Restlet Studio是一款免费的工具,他允许RAML和基于Swagger的API之间的转换,同时支持Restlet, Node和JAX-RS。
链接:[restlet.org](restlet.org)
NETKERNEL:
NetKernel是一套非常有意思的RESTful系统,他支持各种架构风格的微核环境。它得益于在软件体系结构中采用Web的经济学特性。你可以认为他是一种“引进的REST”。然而,RESTful的系统在外部看起来相差都不大,NetKernel也是如此。
链接: [netkernel.org](netkernel.org)
PLAY:
当前有两个主要的Scala语言REST框架。PLAY就是其中之一。
链接:[playframework.com](playframework.com)
SPRAY:
另外一个Scala语言REST框架。主要运作于Akka模式。
链接: [spray.io](spray.io)
EXPRESS:
Node.js的REST框架。
链接: [expressjs.com](expressjs.com)
HAPI:
另一个Node.js的REST框架。
链接: [hapijs.com](hapijs.com)
SINATRA:
Ruby的RESTful框架。
链接: [sinatrarb.com](sinatrarb.com)
三.客户端工具
我们的确可以使用浏览器来调用REST,但是在创建和测试面向资源的系统中,使用一些客户端工具是更为方便和高效的。
CURL:
CURL是一种广受欢迎的命令行工具,它可以调用各种资源上的各种协议。
链接: [curl.haxx.se](curl.haxx.se)
HTTPIE:
HTTPIE是一款非常灵活,易于使用的客户端工具。它通过HTTP进行资源的交互。
链接: [httpie.org](httpie.org)
POSTMAN:
POSTMAN是一款全面的API测试工具。它可以捕获和重置各种请求,使用各种授权认证。一些早期的命令行工具也可以实现需要的大部分功能,但是POSTMAN作为一款全新的桌面应用,他大大的降低了开发者的工作量,提高了工作效率。
原文地址:https://dzone.com/refcardz/rest-foundations-restful
.NET社区新闻,深度好文,微信中搜索dotNET跨平台或扫描二维码关注