REST协议解密(原创)
REST协议解密
REST 全称是什么?REST是一种技术?是一种标准?是一种开发规范?还是一种架构?还是其他?本节内容将为您解密。
本节我们将从以下几个维度展开叙述:
1Web技术发展与REST的由来——讲历史
2REST架构风格的推导过程——讲过程
3REST定义——讲定义
4REST关键原则——讲原则
5总结REST风格的架构特点——讲特点
6REST架构风格的优点&缺点——讲辩证
1Web技术发展与REST的由来
为什么要先从Web技术发展史开始讲起呢?常言道“以铜为镜,可以正衣冠;以古为镜,可以知兴替;以人为镜,可以明得失”,又道是“疑今者,察之古;不知来者,视之往”。我们熟悉技术的发展历史,就能从历史的变迁中找到技术发展的脉搏,找到启示和借鉴,这对我们了解某些技术和将来学习新技术都能奠定基础,把握方向,少走弯路。
不知道读者朋友们有没有想过网址为什么是WWW开头?WWW代表什么含义呢?WWW中文译为万维网,是World Wide Web的简称,这在前后端开发中是司空见惯的字符串。
Web的技术基础有哪些?从技术架构层面上看,Web的技术架构包括了四个基石:URI、HTTP、HyperText、MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型。这四个基石相互支撑,相互助力,共同推动着Web这座宏伟的大厦以几何级数的速度迅速发展起来。
在Web开发技术的历程中,Web开发技术的经历了5个阶段,分别是静态内容阶段、CGI(Common Gateway Interface)程序阶段、脚本语言阶段、瘦客户端应用阶段、RIA(Rich Internet Application)应用阶段和移动Web应用阶段。其中:
在静态内容阶段,Web由静态HTML文档组成,Web服务器有点像支持超文本的共享文件服务器。
在CGI程序阶段,Web服务器增加了编程API,研发人员可以通过CGI协议完成程序开发,这类应用程序被称作CGI程序。
在脚本语言阶段,服务器端先后出现了ASP、PHP、JSP、ColdFusion等支持Session的脚本语言技术,浏览器端则出现了Java Applet、JavaScript等技术。基于这些技术,网站可以为用户提供更加丰富的动态内容。
在瘦客户端应用阶段,在服务器端出现了独立于Web服务器的应用服务器,出现了Web MVC开发模式。基于这些框架开发的Web应用,通常都是瘦客户端应用。
在RIA应用阶段,出现了多种RIA技术,大幅改善了Web应用的用户体验,如最为广泛的RIA技术DHTML+Ajax,Ajax技术支持前端在不刷新页面的情况下动态更新页面中的局部内容,使得用户的体验效果显著提升。这一时期也诞生了大量的Web前端DHTML开发库,如Prototype、Dojo、ExtJS、jQuery/jQuery UI。其他的RIA技术还有Adobe公司的Flex、微软公司的Silverlight、Sun公司的JavaFX(现在为Oracle公司所有)等等。
在移动Web应用阶段,出现了大量面向移动设备的Web应用开发技术。除了Android、iOS、Windows Phone等操作系统平台原生的开发技术之外,基于HTML5的开发技术也变得非常流行。
从上述Web开发技术的发展过程可以得出结论,Web从最初其设计者所构思的主要支持静态文档的阶段,逐渐变得越来越动态化;Web应用的交互模式变得越来越复杂,从静态文档发展到以内容为主的门户网站、电子商务网站、搜索引擎、社交网站,再到以娱乐为主的大型多人在线游戏、手机游戏。
那Web开发技术 和 REST 什么关系呢?上文提及Web的技术架构包括了四个基石,其中之一就是HTTP协议,这里需要简要介绍一下HTTP协议的发展历程。
1995年CGI、ASP等技术出现后,沿用多年、面向静态文档的HTTP/1.0协议已无法满足Web应用的开发需求,因此需要设计新版本的HTTP协议。于是,HTTP/1.0协议专家组成立。在这些专家之中,有一位名叫Roy Fielding的年轻人脱颖而出,显示出了不凡的洞察力,后来Roy Fielding成为了HTTP/1.1协议专家组的负责人。而Roy Fielding还是Apache HTTP服务器的核心开发者,更是Apache软件基金会的合作创始人。
HTTP/1.1协议的第一个草稿于1996年1月发布,后经三年有余的反复修订和论证,于1999年6月成为了IETF的正式规范。
2000年,Roy Fielding在其的博士学位论文《Architectural Styles and the Design of Network-based Software Architectures》(官网地址:http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm)中,系统、严谨地阐述了这套理论框架,并且使用这套理论框架推导出了一种新的架构风格,并且为这种架构风格取了一个令人轻松愉快的名字“REST”——Representational State Transfer(表述性状态转移)的缩写。
2007年1月,支持REST开发的Ruby on Rails 1.2版发布,特别的是Rails将支持REST开发作为其未来发展中的优先内容。Ruby on Rails的创始人DHH做了一个名为“World of Resources”的精彩演讲,DHH在Web开发技术社区中的强大影响力,使得REST一下子处在Web开发技术舞台的聚光灯之下。在Rails等新兴Web开发技术的兴起的推波助澜之下,Web开发技术社区掀起了一场重归Web架构设计本源的运动,REST架构风格得到了越来越多的关注,现在各种流行的Web开发框架几乎没有不支持REST开发的了。
而广大的开发人员也纷纷投身REST架构风格的学习。当然大多数Web开发者都是通过阅读REST开发框架的文档,以及通过一些例子代码来学习REST开发的。不过,通过例子代码来学习REST有非常大的局限性。因为REST并不是一种具体的技术,也不是一种具体的规范,而是一种内涵非常丰富的架构风格。
虽然通过例子代码来学习REST,能“短平快”地学习到一种有趣的Web开发技术,但并不能全面深入的理解REST究竟是什么,甚至还会误以为这些简单的例子代码就是REST本身,REST不过是一种简单的Web开发技术而已。这有点类似像盲人摸象,有的人摸到了象鼻子、有的人摸到了象耳朵、有的人摸到了象腿、有的人摸到了象尾巴。摸象的众人都坚信自认为感觉到的大象才是最真实的大象,而其他人的感觉都是错误的,但现实往往恰恰相反。
2REST架构风格的推导过程——讲过程
Roy Fielding在批判性继承前人研究成果的基础上,建立起来一整套研究和评价软件架构的方法论。这套方法论的核心是“架构风格”这个概念。
架构风格是一种研究和评价软件架构设计的方法,它是比架构更加抽象的概念。一种架构风格是由一组相互协作的架构约束来定义的。架构约束是指软件的运行环境施加在架构设计之上的约束。
Roy Fielding的REST架构风格的推导过程如下所示:
REST架构风格的推导过程
如上图所示,每一个椭圆形里面的缩写词代表了一种架构风格,而每一个箭头边的单词代表了一种架构约束。其中:
RR是Replicated Repository的简写,可译为复制仓库,RR利用多个进程提供相同的服务,来改善数据的可访问和可伸缩。
COD是Code-On-Demand的简写,可译为按需代码。
$表示Cache,指的是复制个别请求的结果,以便可以被后面的请求重。
CSS是Client-Stateless-Server的简写,可译为客户无状态服务器。
LCS是Layered-Client-Server的简写,可译为分层客户服务器。
VM是Virtual Machine的简写,可译为虚拟机风格。
通过上图的推导,Roy Fielding得出了REST架构风格最重要的6个架构约束,即客户-服务器(Client-Server)、无状态(Stateless)、缓存(Cache)、统一接口(Uniform Interface)、分层系统(Layered System)和 按需代码(Code-On-Demand)。其中:
客户-服务器是指通信只能由客户端单方面发起,表现为请求-响应的形式。
无状态是指通信的会话状态(Session State)应该全部由客户端负责维护。
缓存是指响应内容可以在通信链的某处被缓存,以改善网络效率。
统一接口是指通信链的组件之间通过统一的接口相互通信,以提高交互的可见性。
分层系统是指通过限制组件的行为,将架构分解为若干等级的层。
按需代码是指支持通过下载并执行一些代码,对客户端的功能进行扩展。
HTTP/1.1协议作为一种REST架构风格的架构实例,其架构演变经历了如下两图的过程;
如上图所示,用户代理处在三个并行交互(a、b和c)的中间,用户代理的客户端连接器缓存无法满足请求,因此它根据每个资源标识符的属性和客户端连接器的配置,将每个请求路由到资源的来源:
请求(a)被发送到一个本地代理,代理随后访问一个通过DNS查找发现的缓存网关,该网关将这个请求转发到一个能够满足该请求的来源服务器,服务器的内部资源由一个封装过的对象请求代理(object request broker)架构来定义。
请求(b)直接发送到一个来源服务器,它能够通过自己的缓存来满足这个请求。
请求(c)被发送到一个代理,它能够直接访问WAIS(一种与Web架构分离的信息服务),并将WAIS的响应翻译为一种通用的连接器接口能够识别的格式。
上图中,每一个组件只知道与它们自己的客户端或服务器连接器的交互。
3REST定义——讲定义
REST,即REpresentational State Transfer,可译为表述性状态转移。
REST是所有Web应用都应该遵守的架构设计指导原则。
当然,REST并不是法律法规。如果软件开发实践中违反了REST的指导原则,仍然能够实现应用的功能。但是违反了REST的指导原则,会付出很多代价,特别是对于大流量的网站。
4REST关键原则——讲原则
REST有5个关键原则,分别是Resource、Hypertext Driven、Uniform Interface、Representation、State Transfer。其中:
Resource,可译为资源,表示为所有事物定义ID ;
Hypertext Driven,可译为超文本驱动,表示将所有事物链接在一起;
Uniform Interface,可译为统一接口,表示使用标准方法;
Representation,可译为资源的表述,表示资源多重表述的方式;
State Transfer,可译为状态转移,表示无状态地通信。
注:读者在翻译外文文献时,可参考严复在《天演论》中的“译例言”讲到:
“译事三难:信、达、雅
这三个原则的核心在于意译。
4.1资源(Resource)
资源其实可以看作是一种看待服务器的方式 。
与面向对象设计类似,资源是以名词为核心来组织的。
一个资源可以由一个或多个URI来标识。URI既是资源的名称,也是资源在Web上的地址。对某个资源感兴趣的客户端应用,可以通过资源的URI与其进行交互访问获取。
将服务器看作是由很多离散的资源组成,每个资源是服务器上一个可命名的抽象概念。资源可以是服务器文件系统中的一个文件,也可以是数据库中的一张表等等。
上文提到资源意味着为所有事物定义ID,也就是说每个事物都是可被标识的,都会拥有一个的ID标识符。在Web开发中,代表ID的统一概念就是URI。URI构成了一个全局命名空间,使用URI标识你的关键资源意味着它们获得了一个唯一、全局的ID。
这里读者要能区分URI、URL和URN:
URI,即Uniform Resource Identifier :统一资源标识符, 包括 URL 和 URN
URL,即Uniform Resource Locator :统一资源定位符, 常见如下的web url , ftp url 。
URN,即Uniform Resource Name :统一资源名称, 例如tel:+1-888-888-8888
设计URI的4个原则是:
一是要注意它们是名词;
二是要注意区分单复数;
三是要注意 URI 有长度限制, 建议小于1k;
四是要注意在 URI 中不要放未经加密的敏感信息, 即使使用TLS/HTTPS。
在URI中有几个符号需要特别注意:
1)/ 表示层次关系, 例如https://www.elastic.co/cn/products/elasticsearch;
2);, 来表示并列关系, 例如https://www.citys.com/axis;x=0,y=9 sip:user@domain.com;foo=bar;x=y
3)- 来提高可读性, 最好全用小写, 例如https://www.apple-fan.com/
4)用参数或者HTTP Range Header 来限定范围, 例如
https://www.citys.com/sortbyAsc=name&fileds=email,title&limit=10&start=20
4.2超文本驱动
超文本驱动意味着将所有事物链接在一起。超媒体被当作应用状态引擎(Hypermedia As The Engine of Application State,简称HATEOAS),其核心是超媒体概念,换句话说是链接的思想。
引入链接后是我们可以将Web应用看作是一个由很多状态组成的有限状态机。资源之间通过超链接相互关联,超链接既代表资源之间的关系,也代表可执行的状态迁移。
使用URI表示链接时,链接可以指向由不同应用、不同服务器甚至位于不同地域不同洲际的不同公司提供的资源——因为URI命名规范是全球标准,构成Web的所有资源都可以互联互通。
超媒体原则还意味着应用“状态”,服务器端为客户端提供一组链接,使客户端能通过链接将应用从一个状态改变为另一个状态。而链接恰恰是构成动态应用的非常有效的方式。
因此链接成就了现在的Web。
4.3统一接口
统一接口意味着使用标准方法。
按REST要求,必须通过统一的接口来对资源执行各种操作。对于每个资源只能执行一组有限的操作。
在RESTful HTTP方式中,一般开发人员通过组成HTTP应用协议的通用接口访问服务程序。在HTTP/1.1协议中,已经定义了一个操作资源的统一接口,主要包括以下内容:
<!--[if !supportLists]--> <!--[endif]-->7个HTTP方法:POST、GET、PUT、DELETE、PATCH、HEAD、OPTIONS等。
<!--[if !supportLists]--> <!--[endif]-->HTTP头信息(可自定义)
<!--[if !supportLists]--> <!--[endif]-->HTTP响应状态代码(可自定义)
<!--[if !supportLists]--> <!--[endif]-->一套标准的内容协商机制
<!--[if !supportLists]--> <!--[endif]-->一套标准的缓存机制
<!--[if !supportLists]--> <!--[endif]-->一套标准的客户端身份认证机制
对开发人员而言,程序代码将从下面两张图中转变。
4.4资源的表述
资源的表述是一段对资源在某个特定时刻的状态的描述。资源可以在客户端-服务器端之间转移传递。
资源的表述可以有多种格式,如HTML、XML、JSON、文本、图片、视频、音频等。资源的表述格式可以通过协商机制来确定。请求-响应的表述通常使用不同的格式。
4.4状态转移
状态转移意味着无状态通信。这里的状态转移是指在客户端和服务器端之间转移(transfer)。通过转移和操作资源的表述,来间接实现操作资源的目的。
无状态意味着服务器的变化对客户端是不可见的,是不透明的。这主要是为了保证架构设计的可伸缩性和可拓展性。试想一下,如果服务器需要存储每个客户端状态,那么大量的客户端交互会严重影响服务器的内存可用空间。
5总结REST风格的架构特点
REST架构设计优秀程度的判断标准通常有6个:分别是面向资源(Resource Oriented)、可寻址(Addressability)、连通性(Connectedness)、无状态(Statelessness)、统一接口(Uniform Interface)、超文本驱动(Hypertext Driven)。
6REST架构风格的优点&缺点——讲辩证
REST架构设计的优点有简单性、可伸缩、松耦合。需要指出的是REST架构设计不是银弹。在实时性要求很高的应用,REST的表现不如RPC。因此架构设计和技术选型时需要针对具体的运行环境来具体问题具体分析。
上一篇: html5中什么元素用于描述文档
下一篇: 几种常见的序列化和反序列化协议
推荐阅读