漫谈 rest 架构风格 -凯发k8网页登录

java, c , linux c, c#.net 技术,软件架构,领域建模,it 项目管理

1.      什么是rest

rest是representational state transfer的缩写,来源于r. fielding的一篇博士论文:

rest不是什么规范,而是一种架构,一种网络应用的架构。可以把rest理解成一种设计模式,就像其他设计模式一样,只不过rest这种设计模式是应用在网络应用架构上的。

1.1 rest的含义

为了进一步理解什么是rest,让我们看看representational state transfer这三个英文单词分别表示什么意思:

  • representational

中文直译:代表的,表像的。如果把web服务器端中所有的东西(数据)都看作是资源(resource),那么呈现在用户面前(客户端)的就是资源的表像(representation)。同一个资源可能有不同表像,例如一个人作为一个resource,那么他的表像(representation)可以是一张图片(相片),也可以是一个xml描述的个人信息,等等。每一个资源都有自己的唯一标识(uri)。

  • state

中文直译:状态。这个比较难理解。首先这个状态是客户端的状态,而不是服务器端的状态(在rest中,服务器端应该是无状态的)。那么,把state和representation联系在一起(representational state),可以理解成:每一个资源(resource)在客户端的表像(representation)就是客户端的一个状态(state)。

  • transfer

中文直译:转移。当用户通过不同的uri访问不同的资源时,客户端的表像(representation)也会随着变化,也就意味着客户端的状态变更(transfer)了,连起来就是:representational state transfer。

 

1.2 rest架构的特点

  • rest是一种架构,而不是一个规范。
  • rest是一种典型的client-server架构,但是强调瘦服务器端,服务器端只应该处理跟数据有关的操作,所有有关显示的工作都应该放在客户端。
  • rest架构中,服务器是无状态的,也就是说服务器不会保存任何与客户端的会话状态信息。所有的状态信息只能放在双方沟通的message(消息)中。
  • rest架构是幂等的,对于相同的请求,服务器返回的结果也是相同的,因此服务器端返回的结果是可以缓存的,既可以存在客户端也可以存在代理服务器端。
  • rest架构中,所有的操作都是基于统一的方式进行的:
    • 每个resource都有一个唯一的标识。
    • 通过representation(客户端)来处理resource(服务器端)。也就是说,客户端不能直接操作服务器端的resource,只能通过对相应的representation的操作,并发送相应的请求,最后由服务器端来处理resource并返回结果。
    • 客户端和服务器端传送的任何一个message(消息),都应该是自描述的。也就是说处理这个message所需要的上下文环境都应该包含在这个message当中。
    • 多媒体的交互系统,客户端和服务器端传送的内容可以是文档,图片,声音等等多媒体数据,这也是一个resource能够对应不同的representation(例如文档,图片等)的基础。
  • 分层结构,像tcp/ip的分层结构一样,第n层使用第n-1层提供的服务并为第n 1层提供服务。在rest中,client-server之间加入了proxy层和gateway层。在这些中间层可以加入一些业务处理以外的功能,譬如:负载均衡,安全控制等等。
  • code-on-demand,客户端可以访问服务器端的resource,但并不知道如何处理服务器端返回的结果,这个处理过程的代码应该是从服务器端发送过来,然后在客户端执行,也就是说客户端的功能是根据需要动态从服务器端获得的。一个很简单的例子,applet就是从服务器端下载然后在客户端执行的。注意,这个特性是可选的(optional),也就是说在你的rest实现当中,可以不考虑这个特性。


rest架构风格是全新的针对web应用的开发风格,是当今世界最成功的互联网超媒体分布式系统架构,它使得人们真正理解了http协议本来面貌。随着rest架构成为主流技术,一种全新的互联网网络应用开发的思维方式开始流行。

  一、rest是什么
  rest是英文representational state transfer的缩写,中文翻译为“表述性状态转移”,他是由roy thomas fielding博士在他的论文 《architectural styles and the design of network-based software architectures》中提出的一个术语。rest本身只是为分布式超媒体系统设计的一种架构风格,而不是标准。
  基于web的架构,实际上就是各种规范的集合,这些规范共同组成了web架构。比如http协议,比如客户端服务器模式,这些都是规范。每当我们在原有规范的基础上增加新的规范,就会形成新的架构。而rest正是这样一种架构,他结合了一系列的规范,而形成了一种新的基于web的架构风格。

  传统的web应用大都是b/s架构,它包括了如下一些规范 。
  1.客户-服务器:这种规范的提出,改善了用户接口跨多个平台的可移植性,并且通过简化服务器组件,改善了系统的可伸缩性。最为关键的是通过分离用户接口和数据存储这两个关注点,使得不同用户终端享受相同数据成为了可能。
  2.无状态性:无状态性是在客户-服务器约束的基础上添加的又一层规范。他要求通信必须在本质上是无状态的,即从客户到服务器的每个request都必须包含理解该request所必须的所有信息。这个规范改善了系统的可见性(无状态性使得客户端和服务器端不必保存对方的详细信息,服务器只需要处理当前request,而不必了解所有的request历史),可靠性(无状态性减少了服务器从局部错误中恢复的任务量),可伸缩性(无状态性使得服务器端可以很容易的释放资源,因为服务器端不必在多个request中保存状态)。同时,这种规范的缺点也是显而易见得,由于不能将状态数据保存在服务器上的共享上下文中,因此增加了在一系列request中发送重复数据的开销,严重的降低了效率。
  3.缓存:为了改善无状态性带来的网络的低效性,我们填加了缓存约束。缓存约束允许隐式或显式地标记一个response中的数据,这样就赋予了客户端缓存response数据的功能,这样就可以为以后的request共用缓存的数据,部分或全部的消除一部分交互,增加了网络的效率。但是用于客户端缓存了信息,也就同时增加了客户端与服务器数据不一致的可能,从而降低了可靠性。

  b/s架构的优点是其部署非常方便,但在用户体验方面却不是很理想。为了改善这种情况,我们引入了rest。
  rest在原有的架构上增加了三个新规范:统一接口、分层系统和按需代码。
  1.统一接口:rest架构风格的核心特征就是强调组件之间有一个统一的接口,这表现在rest世界里,网络上所有的事物都被抽象为资源,而rest就是通过通用的链接器接口对资源进行操作。这样设计的好处是保证系统提供的服务都是解耦的,极大的简化了系统,从而改善了系统的交互性和可重用性。并且rest针对web的常见情况做了优化,使得rest接口被设计为可以高效的转移大粒度的超媒体数据,这也就导致了rest接口对其它的架构并不是最优的。
  2.分层系统:分层系统规则的加入提高了各种层次之间的独立性,为整个系统的复杂性设置了边界,通过封装遗留的服务,使新的服务器免受遗留客户端的影响,这也就提高了系统的可伸缩性。
  3.按需代码:rest允许对客户端功能进行扩展。比如,通过下载并执行applet或脚本形式的代码,来扩展客户端功能。但这在改善系统可扩展性的同时,也降低了可见性。所以它只是rest的一个可选的约束。
     
  二、rest的设计准则
  rest架构是针对web应用而设计的,其目的是为了降低开发的复杂性,提高系统的可伸缩性。rest提出了如下设计准则:
1.网络上的所有事物都被抽象为资源(resource);
2.每个资源对应一个唯一的资源标识符(resource identifier); 
3.通过通用的连接器接口(generic connector interface)对资源进行操作;
4.对资源的各种操作不会改变资源标识符;
5.所有的操作都是无状态的(stateless)。
  rest中的资源所指的不是数据,而是数据和表现形式的组合,比如“最新访问的10位会员”和“最活跃的10为会员”在数据上可能有重叠或者完全相同,而由于他们的表现形式不同,所以被归为不同的资源,这也就是为什么rest的全名是representational state transfer的原因。资源标识符就是uri(uniform resource identifier),不管是图片,word还是视频文件,甚至只是一种虚拟的服务,也不管你是xml格式,txt文件格式还是其它文件格式,全部通过uri对资源进行唯一的标识。
  rest是基于http协议的,任何对资源的操作行为都是通过http协议来实现。以往的web开发大多数用的都是http协议中的get和post方法,对其他方法很少使用,这实际上是因为对http协议认识片面的理解造成的。http不仅仅是一个简单的运载数据的协议,而是一个具有丰富内涵的网络软件的协议。他不仅仅能对互联网资源进行唯一定位,而且还能告诉我们如何对该资源进行操作。http把对一个资源的操作限制在4个方法以内:get,post,put和delete,这正是对资源crud操作的实现。由于资源和uri是一一对应的,执行这些操作的时候uri是没有变化的,这和以往的web开发有很大的区别。正由于这一点,极大的简化了web开发,也使得uri可以被设计成更为直观的反映资源的结构,这种uri的设计被称作restful的uri。这位开发人员引入了一种新的思维方式:通过url来设计系统结构。当然了,这种设计方式对一些特定情况也是不适用的,也就是说不是所有的uri都可以restful的。
  rest之所以可以提高系统的可伸缩性,就是因为它要求所有的操作都是无状态的。由于没有了上下文(context)的约束,做分布式和集群的时候就更为简单,也可以让系统更为有效的利用缓冲池(pool)。并且由于服务器端不需要记录客户端的一系列访问,也减少了服务器端的性能。

    三、使用rest架构
  对于开发人员来说,关心的是如何使用rest架构,这里我们来简单谈谈这个问题。rest不仅仅是一种崭新的架构,它带来的更是一种全新的web开发过程中的思维方式:通过url来设计系统结构。在rest中,所有的url都对应着资源,只要url的设计是良好的,那么其呈现的系统结构也就是良好的。这点和tdd(test driven development)很相似,他是通过测试用例来设计系统的接口,每一个测试用例都表示一系列用户的需求。开发人员不需要一开始就编写功能,而只需要把需要实现的功能通过测试用例的形式表现出来即可。这个和rest中通过url设计系统结构的方式类似,我们只需要根据需求设计出合理地url,这些url不一定非要链接到指定的页面或者完成一些行为,只要它们能够直观的表现出系统的用户接口。根据这些url,我们就可以方便的设计系统结构。从rest架构的概念上来看,所有能够被抽象成资源的东西都可以被指定为一个url,而开发人员所需要做的工作就是如何能把用户需求抽象为资源,以及如何抽象的精确。因为对资源抽象的越为精确,对rest的应用来说就越好。这个和传统mvc开发模式中基于action的思想差别就非常大。设计良好的url,不但对于开发人员来说可以更明确的认识系统结构,对使用者来说也方便记忆和识别资源,因为url足够简单和有意义。按照以往的设计模式,很多url后面都是一堆参数,对于使用者来说也是很不方便的。
  既然rest这么好用,那么是不是所有的web应用都能采取此种架构呢?答案是否定的。我们知道,直到现在为止,mvc(model-view-controller)模式依然是web开发最普遍的模式,绝大多数的公司和开发人员都采取此种架构来开发web应用,并且其思维方式也停留于此。mvc模式由数据,视图和控制器构成,通过事件(event)触发controller来改变model和view。加上webwork,struts等开源框架的加入,mvc开发模式已经相当成熟,其思想根本就是基于action来驱动。从开发人员角度上来说,贸然接受一个新的架构会带来风险,其中的不确定因素太多。并且rest新的思维方式是把所有用户需求抽象为资源,这在实际开发中是比较难做到的,因为并不是所有的用户需求都能被抽象为资源,这样也就是说不是整个系统的结构都能通过rest的来表现。所以在开发中,我们需要根据以上2点来在rest和mvc中做出选择。我们认为比较好的办法是混用rest和mvc,因为这适合绝大多数的web应用开发,开发人员只需要对比较容易能够抽象为资源的用户需求采取rest的开发模式,而对其它需求采取mvc开发即可。这里需要提到的就是ror(ruby on rails)框架,这是一个基于ruby语言的越来越流行的web开发框架,它极大的提高了web开发的速度。更为重要的是,ror(从1.2版本起)框架是第一个引入rest做为核心思想的web开发框架,它提供了对rest最好的支持,也是当今最成功的应用rest的web开发框架。实际上,ror的rest实现就是rest和mvc混用,开发人员采用ror框架,可以更快更好的构建web应用。
  对开发人员来说,rest不仅仅在web开发上贡献了自己的力量,同时也让我们学到了如何把软件工程原则系统地应用于对一个真实软件的设计和评估上。


理解rest软件架构

 一种思维方式影响了
行业的发展。软件是当今世界上最成功的的超媒体分布式系统。它让人们真正理解我们的协议http本来面貌。它正在成为网络服务的主流,同时也正在改变互联网的网络软件开发的全新思维方式。ajax技术和框架把rest软件架构思想真正地在实际中很好表现出来。今天微软也已经应用rest并且提出把我们现有的网络变成为一个,这种网络将会使得搜索更加智能化。

rest与http协议

rest软件架构是由roy thomas fielding博士在2000年首次提出的。他为我们描绘了开发基于互联网的网络软件的蓝图。rest软件架构是一个抽象的概念,是一种为了实现这一互联网的超媒体分布式系统的行动指南。利用任何的技术都可以实现这种理念。而实现这一软件架构最著名的就是http协议。通常我们把rest也写作为rest/http,在实际中往往把rest理解为基于http的rest软件架构,或者更进一步把rest和http看作为等同的概念。

今天,http是互联网上最广泛的计算机协议。http不是一个简单的运载数据的协议,而是一个具有丰富内涵的网络软件的协议。它不仅仅能够对于互联网资源进行唯一定位,而且还能告诉我们对于该资源进行怎样运作。这也是rest软件架构当中最重要的两个理念。而rest软件架构理念是真正理解http协议而形成的。有了rest软件架构理念出现,才使得软件业避免了对http协议的片面理解。只有正确的理论指导,才能避免在软件开发的实际工作过程中少走弯路。

rest与uri(资源定位)

rest软件架构之所以是一个超媒体系统,是因为它可以把网络上所有资源进行唯一的定位,不管你的文件是图片、文件word还是文件,也不管你的文件是txt文件格式、xml文件格式还是其它文本文件格式。它利用支持http的tcp/ip协议来确定互联网上的资源。

rest与crud原则

rest软件架构遵循了crud原则,该原则告诉我们对于资源(包括网络资源)只需要四种行为:创建(create)、获取(read)、更新(update)和销毁(delete)就可以完成对其操作和处理了。其实世界万物都是遵循这一规律:生、变、见、灭。所以计算机世界也不例外。这个原则是源自于我们对于数据库表的数据操作:insert(生)、select(见)、update(变)和delete(灭),所以有时候crud也写作为rudi,其中的i就是insert。这四个操作是一种原子操作,即一种无法再分的操作,通过它们可以构造复杂的操作过程,正如数学上四则运算是数字的最基本的运算一样。

rest与网络服务

尽管在java语言世界中网络服务目前是以soap技术为主,但是rest将是是网络服务的另一选择,并且是真正意义上的网络服务。基于rest思想的网络服务不久的将来也会成为是网络服务的主流技术。rest不仅仅把http作为自己的数据运输协议,而且也作为直接进行数据处理的工具。而当前的网络服务技术都需要其它手段来完成数据处理工作,它们完全独立于http协议来进行的,这样增加了大量的复杂软件架构设计工作。rest的思想充分利用了现有的http技术的网络能力。在德国电视台上曾经出现过一个这样的五十万欧元智力题:如何实现网络服务才能充分利用现有的http协议?该给出了四个答案:去问微软;wsdl2.0/soap1.2;ws-transfer;根本没有。这个问题告诉我们http并不是一个简单的数据传来传去的协议,而是一个聪明的会表现自己的协议,这也许是rest = representational state transfer的真正含义。

实际上目前很多大公司已经采用了rest技术作为网络服务,如google、amazon等。在java语言中重要的两个以soap技术开始的网络服务框架xfire和axis也把rest作为自己的另一种选择。它们的新的项目分别是。java语言也制定关于rest网络服务规范:jax-rs: java api for restful web services (jsr 311)。相信还会出现更多与rest相关的激动人心的信息。

rest与ajax技术

尽管ajax技术的出现才不到两年时间,但是ajax技术遵循了rest的一些重要原则。ajax技术充分利用了http来获取网络资源并且实现了http没有的对于异步数据进行传输的功能。ajax技术还使得软件更好地实现分布性功能,在一个企业内只要一个人下载了ajax引擎,其它企业内部的人员,就可以共享该资源了。ajax技术遵守rest准则的应用程序中简单和可伸缩的架构,凡是采用ajax技术的页面简洁而又丰富,一个页面表现了丰富多彩的形态。

ajax技术还使用了一种不同于xml格式的json文件格式,这个意义在哪里呢?在rest软件架构下我们不能对于xml文件进行序列化处理,这样程序员必须要使用自己的xml绑定框架。而以序列化的javascript对象为基础的json已经获得了广泛认可,它被认为能以远比xml更好的方式来序列化和传输简单数据结构,而且它更简洁。这对rest是一个极大贡献和补充。

当前的网络应用软件还违背了rest的“无状态”约束。rest服务器只知道自己的状态。rest不关心客户端的状态,客户端的状态自己来,这是ajax技术的应用之地。通过ajax技术,可以发挥有状态网络客户机的。而rest的服务器关心的是从所有网络客户端发送到服务器操作的顺序。这样使得互联网这样一个巨大的网络得到有序的管理。

rest与rails框架

on rails框架(简称rails或者rails框架)是一个基于ruby语言的越来越流行的网络应用软件开发框架。它提供了关于rest最好的支持,也是当今应用rest最成功的一个软件开发框架。rails框架(从版本1.2.x起)成为了第一个引入rest作为核心思想的主流网络软件开发框架。在rails框架的充分利用了rest软件架构之后,人们更加坚信rest的重要性和必要性。rails利用rest软件架构思想对网络服务也提供了一流的支持。从最直观的角度看待rest,它是网络服务最理想的手段,但是rails框架把rest带到了网络应用软件开发框架。这是一次飞跃,让rest的思想从网络服务的应用提升到了网络应用软件开发。利用rest思想的simply_restful插件已经成为了rails框架的核心内容。

rest安全性

我们把现有基于soap的网络服务和基于rest/http网络服务作个比喻,前者是一种传统的寄信方式,而后者是现代网络的电子邮件方式。要是是寄信和电子邮件都有病毒存在的话,传统的寄信被送到对方就很危险,而电子邮件是开发的,电子邮件供应商比如google为我们检查了电子邮件是否有病毒。这里并不是说明soap网络服务消息包含义病毒,而是说明http是无法处理soap信息包究竟好不好,需要额外的软件工具这一问题,包括也用不上和管不了。

rest/http网络服务的信息包可以被防火墙理解和控制。你可以按照操作和链接进行过滤信息包,如你可以规定从外部来的只能读取(get操作)自己服务器的资源。这样对于系统管理员而言使得软件管理更为简单。rest的性还可以利用传输安全协议ssl/tls、基本和摘要式认证(basic und digest authentication)。除了这些rest自身的安全性功能外,还可以利用像基于信息的web services security(jsr 155)作为rest不错的补充。






本博客为学习交流用,凡未注明引用的均为本人作品,转载请注明出处,如有凯发k8网页登录的版权问题请及时通知。由于博客时间仓促,错误之处敬请谅解,有任何意见可给我留言,愿共同学习进步。
posted on 2008-05-15 18:47 jack.wang 阅读(9645) 评论(3)     所属分类: 开发技术
# re: 浅谈rest 2008-05-16 11:43
> http把对一个资源的操作限制在4个方法以内:get,post,put和delete,这正是对资源crud操作的实现。

把http当成crud来使用,将无法发挥rest中"hypermedia as application state engine"所带来的好处。这是roy fielding一再强调的:

  回复  
  

# re: 浅谈rest 2008-05-16 12:37 jack.wang
there seems to be a common thread with most posts here. people
have been busy modeling everything as a resource and now they
want to know how to do everything in a put or delete instead of
any of the other http methods. that is wrong. that is thinking
http is just a "save as..." dialog.

rest is not limited to get, put, and delete. anyone who says so
is just making things up as they go along. rest is limited to the
client being told what to do next by the current state of where
they are now, aside from the entry point(s) we call a bookmark.
that is feasible because the set of methods is uniform, not because
it is limited to crud. post is an equal party in the rest interface,
particularly when actions are being applied to the resources that
are a composite of multiple source resources. so is patch.

doing restful actions on multiple resources is no different from
selecting multiple tunes in itunes and using the info dialog
to set certain properties across all selected tunes. it is a ui issue.
the ui builds a set of actions to perform and then performs them
in whatever way is most efficiently provided by the set of resources
being operated upon. if those resources (or, rather, the index to
those resources) say they can be operated upon as a group by post
of a selection form, then so be it -- that is perfectly restful
even without the benefit of per-resource cache invalidation.
likewise for patch or put to a meta-resource, or proppatch to a
webdav resource, it is restful if there is some engine described
by a representation provided by the origin server that instructs
the client on what to do next.

the goals are to remove coupling and maximize the number of
reusable resources.

....roy  回复  
  

# re: 浅谈rest 2008-05-16 17:28 jack.wang
我看过一些文档,感觉 web service 还不太成熟,只能作为异构系统之间相互集成时的胶水。以前 robbin 写过介绍 web service 的文章对 web service 的定位也基本上是这样。web service 并不适合核心的业务领域,其组件模型相比 corba、ejb 来说是非常不成熟的。核心的应用领域还是要靠 corba、ejb 来建造。
基于 http 只是一个 marketing hype,不要上当。corba 如果配置在 80 端口同样可以穿越防火墙。http 本身就是一个低效的传输协议,基于文本的 xml 更加低效,在高强度的核心应用领域,不要跟我说性能是无关紧要的。另外还有安全性等 corba 已经解决得很好的问题 web service 好象还没有完全解决(是不是老黄历了?)
简单的技术就应该用在简单的场合,一定要在复杂的核心应用领域采用简单的技术是会出问题的。corba 确实很复杂,但是要搞清楚究竟是因为要解决的问题本身很复杂所以技术也很复杂还是因为一帮技术狂人闲的无聊故意搞得这么复杂以便大家对他们顶礼膜拜。
我的看法是 web service 与 corba 的定位不同,所以不存在谁灭掉谁的问题。
一点浅见,欢迎讨论。  回复  
  

网站地图