在介绍restful之前先放一张从之前文章评论里看到的图,我觉得它把soap和rest之间的一些区别形容地非常形象。
在第一篇和第二篇中我们也介绍过,soap协议传递的报文要基于xml格式的soap消息,它定义了非常复杂的xml schemas,因此会让传递的消息变得非常重,而rest是充分利用了http协议本身语义,所以会比较轻量。那么除了这些,rest和我们常用的soap协议又有那些区别呢?rest为什么会被看成是未来webservice的发展趋势?下面就让我们具体来看看什么是rest,什么是restful webservcie。
REST全称是Representational State Transfer,中文意思是表征性状态转移。 它首次出现在2000年Roy Fielding的博士论文中,Roy Fielding是HTTP规范的主要编写者之一。 他在论文中提到:"我这篇文章的写作目的,就是想在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。REST指的是一组架构约束条件和原则。" 如果一个架构符合REST的约束条件和原则,我们就称它为RESTful架构。 REST本身并没有创造新的技术、组件或服务,而隐藏在RESTful背后的理念就是使用Web的现有特征和能力, 更好地使用现有Web标准中的一些准则和约束。虽然REST本身受Web技术的影响很深, 但是理论上REST架构风格并不是绑定在HTTP上,只不过目前HTTP是唯一与REST相关的实例。
是不是被上面一段话整的云里雾里?其实用人话来总结就是:
REST是一种风格是用URL定位资源,用HTTP动词(GET,POST,DELETE,PUT,PATCH )描述操作的协议。RESTful实现REST风格的一种软件架构风格,提供了设计原则和约束条件。REST全称是表征性状态转移,表征指的就是资源。任何事物,只要有被引用到的必要,它就是一个资源。资源可以是实体(例如手机号码),也可以只是一个抽象概念(例如价值) 。下面是一些资源的例子:
某用户的手机号码某用户的个人信息最多用户订购的GPRS套餐两个产品之间的依赖关系某用户可以办理的优惠套餐某手机号码的潜在价值要让一个资源可以被识别,需要有个唯一标识,在Web中这个唯一标识就是URI(Uniform Resource Identifier)。 URI既可以看成是资源的地址,也可以看成是资源的名称。如果某些信息没有使用URI来表示,那它就不能算是一个资源, 只能算是资源的一些信息而已。URI的设计应该遵循可寻址性原则,具有自描述性,需要在形式上给人以直觉上的关联。这里以github网站为例,给出一些还算不错的URI:
https://github.com/githttps://github.com/git/githttps://github.com/git/git/blob/master/block-sha1/sha1.hhttps://github.com/git/git/pullshttps://github.com/git/git/pulls?state=closedhttps://github.com/git/git/compare/master…nextRESTful架构应该遵循统一接口原则,统一接口包含了一组受限的预定义的操作,不论什么样的资源,都是通过使用相同的接口进行资源的访问。接口应该使用标准的HTTP方法如GET,PUT和POST,并遵循这些方法的语义。 如果按照HTTP方法的语义来暴露资源,那么接口将会拥有安全性和幂等性的特性,例如
GET和HEAD请求都是安全的,无论请求多少次,都不会改变服务器状态。GET、HEAD、PUT和DELETE请求都是幂等的,无论对资源操作多少次,结果总是一样的,后面的请求并不会产生比第一次更多的影响。 GET /zoos:列出所有动物园 POST /zoos:新建一个动物园 GET /zoos/ID:获取某个指定动物园的信息 PUT /zoos/ID:更新某个指定动物园的信息(提供该动物园的全部信息) PATCH /zoos/ID:更新某个指定动物园的信息(提供该动物园的部分信息) DELETE /zoos/ID:删除某个动物园 GET /zoos/ID/animals:列出某个指定动物园的所有动物 DELETE /zoos/ID/animals/ID:删除某个指定动物园的指定动物REST的发明者Roy Fielding博士曾经说过“Hypermedia作为应用引擎”是REST的前提, 这不是一个可选项,如果没有Hypermedia,那就不是REST。(摘自Infoq对Fielding博士的第二段访谈)
因此除了符合HTTP协议自身的语义,REST还要满足Hypermedia(超媒体即应用状态引擎(hypermedia as the engine of application state))。
采用Hypermedia的API在响应(response)中除了返回资源(resource)本身外,还会额外返回一组链接(link)。 这组链接描述了对于该资源,消费者(consumer)接下来可以做什么以及怎么做。
这样做的好处是:
1. 不再揣测如何组合使用API 2. 不用再考虑API的版本 3. 彻底与API的内部实现解耦在这里分享一篇详细介绍Hypermedia的文章,写得很好,有兴趣的同学可以点进去了解下。
http://hippoom.github.io/blogs/value-of-hypermedia-from-client-perspective.html
客户端通过HTTP可以获取资源,这个资源一般只是资源的表述。 例如文本资源可以采用html、xml、json等格式,图片可以使用PNG或JPG展现出来
“会话”状态不是作为资源状态保存在服务端的,而是被客户端作为应用状态进行跟踪的。即RESTful 服务是无状态的并且不会为任何客户端保持状态。一个请求不应该依赖过去的请求,服务对待每个请求都是独立的。客户端应用状态在服务端提供的超链接的指引下发生变迁。服务端通过超链接告诉客户端当前状态有哪些后续状态可以进入。
举个栗子,假设我们在阅读一篇需要翻页的文章,我们如果要访问下一页。
有状态的请求就需要记录我们上一次请求的页数PageNo,然后根据PageNo请求下一页
有状态设计: Request1: GET http://MyService/Page/1 Request2: GET http://MyService/NextPageRequest2的请求是要基于Request1请求的页数来进行的,服务器需要记住这个页数,否则Request2无法进行。即Request2需要依赖Request1操作,如果Request1操作不成功,则Request2也不会成功。
而无状态设计中每一步都是独立,我们请求任何一页都不需要知道上一次请求的是哪一页。
无状态设计像这样: Request1: GET http://MyService/Page/1 Request2: GET http://MyService/Page/2 每个请求都能被单独对待。无状态服务更容易设计成集群,更容易维护,更容易伸缩。这样的服务提供了更好的响应时间,因为它们能容易进行负载均衡。随着微服务的概念越来越普及,无状态设计势必会成为未来的趋势。
综上,我们总结下REST的要求:
客户端和服务器结构 通信只能由客户端单方面发起,表现为请求-响应的形式。连接协议具有无状态性 通信的会话状态(Session State)应该全部由客户端负责维护。能够利用Cache(缓存)机制增进性能 服务器返回信息必须被标记是否可以缓存,如果缓存,客户端可能会重用之前的信息发送请求。统一接口(Uniform Interface)层次化的系统 系统组件不需要知道与他交流组件之外的事情。封装服务,引入中间层。按需代码(Code-On-Demand ) - Javascript (可選) 泛指任何按照客户端软件(例如,浏览器)的请求,将可执行的软件程序从服务器计算机发送到客户端的技术。转载于:https://www.cnblogs.com/MarsCheng/p/7234399.html