SOA之(5)——REST的SOA(SOA with REST)概念
REST的SOA(SOA with REST)概念
发展
1992年网站(Web Sites)是在Web浏览器和Web服务器直接通过HTTP传输HTML。

2000年WS-* (Web Services)是在客户端和服务器之间基于HTTP传输SOAP XML格式的数据,服务端用WSDL来规定契约。

2007年RESTful (Web Services)是在客户端和服务器之间基于HTTP传输JSON、PO-XML、RSS格式的数据,服务端用WADL来规定契约。

Web services从哪来?
解决企业软件标准化的问题
企业计算的互用性标准
一个提供消息、描述、发现规范的分层架构
能够快速从底层构建提供解决方案
工具可以将复杂性屏蔽
处理异构(Heterogeneity)
Web应用(Web Applications)与 企业计算(Enterprise Computing)

庞然大物(Big Web Services)
- 复杂难以理解(High perceived complexity)
- 标准化存在问题
- 斗争中(infighting)
- 缺乏架构的一致性(architectural coherence)
- 碎片化(fragmentation)
- 设计委员会(committee)
- 特性膨胀(feature bloat 主要提现在不断新增的文档)
- 缺乏参考实现(reference implementations)
- 标准的标准(Standardization of standards (WS-I))
- 看似另一个CORBA?
- Web services的互用性真的存在?
- 我们真的需要采用XML来提升性能?
一个关于Web Services文档的不完全统计(http://www.tbray.org/ongoing/When/200x/2004/09/21/WS-Research)
正文目录
什么是REST?
RESTful的设计
WS-*与REST的比较
讨论
前瞻
表述性状态转移(REpresentational State Transfer)
REST为Web定义了一个架构风格
它的四个原则可以用HTTP协议来实现
- URI资源识别(Resource Identification)
- 所有资源统一接口(Uniform Interface)
- GET(状态查询、幂等性、缓存)
- POST(创建子资源)
- PUT(更新、状态转换)
- DELETE(删除资源)
- 自解释(Self-Describing),消息的元数据和多种资源表述
- 超链接(Hyperlinks),定义应用的状态转换和资源之间的关系
一个RESTful Web Service的例子

统一接口原则(CRUD的例子)

创建(POST《-》)——创建一个子资源
读取(GET《-)——获取当前资源的状态
更新(PUT -》)—— 初始化或更新一个URI对应的资源状态
删除(DELETE)——清除一个资源(在一个URI失效之后)
统一资源标识符URI(Uniform Resource Indentifier)是什么?
- 因特网对于资源命名和标识的标准
例如:
http://tools.ietf.org/html/rfc3986
http——统一资源标识符方案(URI Scheme)
://tools.ietf.org——授权(Authority)通常是一个主机名
/html/rfc3986——路径(Path)
https://www.google.ch/search?q=rest&start=10#1
?q=rest&start=10——查询(Query)
#1——片段(Fragment)
- REST并不拥护“好”的URI
- 在多数HTTP栈中URI的长度不能大于4Kb
什么是“好”的URI?

URI的设计指南
- 名词(Nouns)优于动词(Verbs)
- URI保持简短
GET /book?isbn=24&action=delete
DELETE /book/24
- 遵从位置通过参数传递的方案
REST URI对于客户端透明的意思是它是由后续的链接提供,而不是通过客户端自行创建
- 不要改变URI
- 真的需要改变时,用重定向实现(redirection)
注意:URI模板引入了客户端和服务端的耦合
高级REST 和 低级REST
关于REST实现的最佳实践有些区别(在本人实际工作中,很多技术实力雄厚的大型企业,对于REST最佳实践的方案也基本可以归为以下两种,而第一种“低级”REST比较普遍)
低级REST(Low REST)
- 用HTTP GET实现幂等请求,其他所有请求都用POST(没有HTTP PUT DELETE等其他方法)
- 响应格式(MIME Type)多种多样(e.g. XHTML, application/json, application/xml)
高级REST(High REST)
- 推荐使用好的URI
- 充分使用4个动词:GET、POST、PUT和DELETE(*)
- 响应体用(Plain Old) XML(**)
补充说明:
(*)有些防火墙或者HTTP的代理可能丢弃PUT/DELETE请求
(**)XML可以被RDF、JSON、YAML或者ATOM(ATOM存在很大的争议)替代
资源表述的格式XML vs. JSON
| XML | JSON(JavaScript Object Notation) |
| —PO-XML | 为AJAX Web应用引入格式供(浏览器-Web服务器通讯) |
| —SOAP(WS-*) | |
| —RSS,ATOM | |
| 半结构化的数据和标准的文本语法 | 文本语法支持序列化非循环的数据结构 |
| 工具:XML Schema,DOM,SAX,Xpath,XSLT,Xquery | 有很多语言支持(不仅仅JavaScript) |
| 每个人都可以解析它(不需要理解) | 不需要扩展 |
| 慢、臃肿 | JSON已经成为AJAX中的X而不是XML |
一个JSON的例子

REST 的优与劣
| 优势(Strengths) | 劣势(Weakness) |
| 简单 —统一接口不可变更 |
混乱(区分high REST和low REST) |
| HTTP/POX 无处不在 | 在前后台系统设计中存在不匹配的情况(异步消息和事件驱动) |
| 无状态/同步交互 | 除了HTTP/SSL不能实现其他的企业应用的风格(*) |
| 可扩展 | |
| 易于理解并采用(轻量级) —只需要一个浏览器,不需要WS中间件 |
对于合适的识别和定位所有应用中的资源时一个挑战 |
| 朴素的方法(grassroot approach) | 缺乏标准(本人认为REST是一个设计风格而非标准) |
| 被所有的Web2.0应用采用 —85%的客户都喜欢Amazon的RESTful API —Google不再支持SOAP/WSDL API |
语法和语义的描述是非正式的(面向用户的) (本人认为这也恰恰是一个优势) |
(*) 关于企业的应用风格(-ilities)参照文章http://www.cnblogs.com/richaaaard/articles/5006681.html
是否不能实现我们还有待探讨
关于RESTful Web Services的设计方法
- 识别资源并暴露成服务(例如,年度风险报表,图书分类,采购订单,缺陷,调查投票等)
- 定义好的URL供寻址
- 理解GET、POST、PUT、DELETE对于一个URI资源的意义
- 设计并记录资源的表述
- 用超链接(hyperlinks)为资源关系建模
- Web服务器实现与部署
- 用浏览器进行测试(当然这里还有其他一些好的辅助测试工具,后面可以专门开文章探讨)
一个简单的Doodle API例子
- 创建一个投票
- 查询一个投票

- 参加投票并创建一个新的子投票资源

- 更新一个一有投票(访问控制头没有显示)

- 当投票结果和决定产生后,投票可以将其删除

更多的信息可以查看Doodle API: http://doodle.com/xsd1/RESTfulDoodle.pdf
(当然在RESTful下也有很多其他的API实现)
REST设计的相关小贴士
- 理解GET、POST、PUT
- GET 是一个只读操作。它可以重复执行多次而不影响资源的状态(幂等性),也可以被缓存
- POST是一个读写操作,可以改变资源的状态,也会读服务器产生影响
- PUT 是一个写操作,但问题是如何正确的使用PUT?因为 PUT /resource/{id}可以被多个客户端并发调用,如何保证资源{id}的唯一性?
- 多种表述形式的妥协(Content-Type)
- 通常客户端可以提供自己可以处理的格式列表 Accept: text/html, application/xml, application/json
- 服务端则自己选择最合适的响应格式200 OK Content-Type: application/json
- GET /resource.html
- GET /resource.xml
- GET /resource.json
服务端通常通过资源表述不同的后缀形式提供不同的内容格式(只是一个best practice而不是标准)
- 异常处理(Idempotent vs. Unsafe)
主要体现在HTTP的标准响应码上

对于GET、PUT、DELETE这些幂等操作,可以执行多次而不会对服务端的状态产生其他影响,可以在服务器宕机或者出现内部错误而恢复过后,重新发起这些请求。对于POST这种非幂等操作就需要在出现异常之后特殊处理,在有些场景下,它也可以被设计成幂等操作来实现:
B = GetBalance() // safe
B = B + 200$ // local
SetBalance(B) // safe
总而言之,对比WS-*和REST
就是一个苹果和一个橘子的对比。一个是中间件互用性的标准,另一个是Web架构的风格。

那我们还是来比较一下SOAP和REST吧
- 先举例
- 概念比较
- REST作为链接
- 技术性比较
- 服务的表述
- 安全
- 状态管理
- 异步消息
举一个RESTful Web 应用的栗子

同样的场景下WS是这样的

REST和SOAP最主要的区别在于
- 对于REST而言,Web是一个任何人都能访问的信息
—应用需要把它的信息通过URI发布到网络
- 对于WS而言,Web是任何传输的消息
—应用可以与网络交互,但是他们处于网络之外

REST是一种链接方式

他们(REST vs. SOAP)是如何描述服务的呢?
| REST | SOAP |
| REST是基于人类可读的文档,它定义了请求的URI和响应(XML,JSON) | 客户端的stubs可以通过WSDL的描述用大多数语言生成 (实际上SOAP也是一种XML,也是可读的) |
| 需要大量的测试和调试,因为URI是手工创建的 (是否有相关工具) |
每个服务都根据自己的语法发布自己的接口 |
| 我们为什么需要强类型的消息? (如果客户端和服务端都很清楚传输的内容是什么) |
强类型 |
| WADL | WSDL1.1(整个开放端口对于GET和POST是统一的) |
| XML 足够了?(实际上有JSON、XML等其他) |
WSDL2.0(更灵活,每个方法的GET or POST可选) |
REST和SOAP安全对比
| REST | SOAP |
| REST的安全就是HTTPs | SOAP的安全定义在WS-Security中 |
| 被证明的(SSL1.0 自1994) | XML加密 |
| XML签名 | |
| —彻底的互用性没有意义 | |
| —性能? | |
| 点到点安全(认证、完整和加密) | 端到端安全,不需要HTTPs |
一直争论的状态还是无状态
| REST | SOAP |
| 显性的状态转换 | 隐性的状态转换 |
| —通信是无状态的 | —服务端可以保持状态 |
| —资源数据包含了有效的状态链接 | —消息只包含数据 |
| —客户端根据链接来获取并维护状态 | —客户端根据服务端的状态机逻辑来维护自己的状态 |
| Session技术 | Session技术 |
| —Cookies(HTTP Headers) | —Session Headers(非标准) |
| —URL Re-writing | |
| —表格字段隐藏 |
异步可靠的消息
- 对于REST来说,HTTP是一个同步的协议,但是它也可以模拟异步消息
POST /queue 202 Accepted
Location:
/queue/message/1230213
____________________________
GET /queue/message/1230213
DELETE
/queue/message/1230213
- SOAP消息可以通过异步协议传输(比如,JMS、MQ等)
- WS-Addressing可以用来定义独立的传输点
- WS-ReliableExchange定义了一个可靠的传输协议(SOAP headers)
REST 和SOAP/WS*的相似点
| REST | SOAP |
| XML | O/XML 绑定 |
| 其他的方式JSON、YAML、RDF | |
| XML Schema | 数据格式的契约需要和接口一起定义 |
| HTTP | 尽管REST认为SOAP误用了POST |
| 松耦合可扩展 | SOAP提供同步异步方式 |
| SOAP认为统一的接口不会改变 |
揭露所谓的秘密
- 许多REST的拥趸认为REST和Web service是不相兼容的
- 实施上:SOAP和WSDL的新版本已经将Web services设计得更“RESTful”
- SOAP1.2
- Response MEP
- Web Method
- WSDL2.0
- HTTP绑定新增了操作级别(per-operation)对于GET、POST指定
- 增加对于safe/cacheable的属性标签
- 但是想让RESTful完全使用Web services还是很困难
(然而市面上有些产品实际上可以支持他们的相兼容)
总结和前瞻
- SOA可以用不同方式实现
- 关注架构如何解决问题以及这些相关标准的价值,而非具体架构和技术的盲从
- SOAP/WS-* 与 REST都有自己的优势和适合的应用场景
- 未来会有融合两种技术优势的中间件技术出现(新SOAP和WSDL标准)
参考:
《SOA设计模式》 由Thomas Erl及其他供稿者合著,作为Thomas Erl关于面向服务计算丛书的一部分,于2009年1月由Prentice Hall出版,ISBN 0136135161,版权所有2009 SOA System Inc.。
Web Services and Service Oriented Architectures@2009 Cesare Pautasso
SOA之(5)——REST的SOA(SOA with REST)概念的更多相关文章
- 服务治理要先于SOA
讲在前面的话: 若企业缺乏对服务变更的控制和规则,那么一个服务在经过几个项目之后,就很有可能被随意更改成多个版本,将来变成什么样更是无法预测.久而久之,降低了服务重用的可能性,提高了服务利用的成本 ...
- SOA相关资料整理分享
昨@幸福框架同学问能否推荐SOA一些资,.想想之前看过不少资料文档,就整理分享下,有需要的可以参考下. 文章链接 理解面向服务的体系结构中企业服务总线场景和解决方案,第 1 部分 SOA 和 web ...
- IDDD 实现领域驱动设计-SOA、REST 和六边形架构
上一篇:<IDDD 实现领域驱动设计-架构之经典分层> 阅读目录: SOA-面向服务架构 REST 与 RESTful 资源(Resources) 状态(State) 六边形架构 DDD ...
- 企业 SOA 设计(1)–ESB 设计
最近为公司完成了一个 ESB 的设计.下面简要说明一下具体的设计方案. 企业 SOA 整体方案 在前一篇<SOA.ESB.NServiceBus.云计算 总结>中说到,SOA 是面向服 ...
- SOA、ESB、NServiceBus、云计算 总结
SOA SOA 是通过功能组件化.服务化,来实现系统集成.解决信息孤岛,这是其主要目标.而更进一步则是实现更快响应业务的变化.更快推出新的应用系统.与此同时,SOA 还实现了整合资源,资源复用. SO ...
- 异构SOA系统架构之Asp.net实现(兼容dubbo)
我们公司技术部门情况比较复杂,分到多个集团,每个集团又可能分为几个部门,每个部门又可能分为多个小组,组织架构比较复杂,开发人员比较多. 使用的编程语言也有点复杂,主流语言有.net(C#).Java. ...
- SOA架构设计经验分享—架构、职责、数据一致性
阅读目录: 1.背景介绍 2.SOA的架构层次 2.1.应用服务(原子服务) 2.2.组合服务 2.3.业务服务(编排服务) 3.SOA化的重构 3.1.保留服务空间,为了将来服务的组合 4.运用DD ...
- 高并发应用场景下的负载均衡与故障转移实践,AgileEAS.NET SOA 负载均衡介绍与实践
一.前言 AgileEAS.NET SOA 中间件平台是一款基于基于敏捷并行开发思想和Microsoft .Net构件(组件)开发技术而构建的一个快速开发应用平台.用于帮助中小型软件企业建立一条适合市 ...
- SOA架构设计(转发)
阅读目录: 1.背景介绍 2.SOA的架构层次 2.1.应用服务(原子服务) 2.2.组合服务 2.3.业务服务(编排服务) 3.SOA化的重构 3.1.保留服务空间,为了将来服务的组合 4.运用DD ...
- 千万用户级别应用系统背后的SOA组件化容器
背景 在<我们的应用系统是如何支撑千万级别用户的>随笔中已经从“宏观”角度去介绍了整个应用系统的布局.组件化是整个系统由头到尾都始终坚持的一个设计原则,其中“SOA组件化容器”也是我们应用 ...
随机推荐
- JDBC基础一
JDBC:java database connectivity SUN公司提供的一套操作数据库的标准规范. JDBC与数据库驱动的关系:接口与实现的关系. JDBC规范(掌握四个核心对象): Driv ...
- 西门子MES解决方案SIMATIC IT在乳制品行业小试牛刀
竞争的白热化,紧缩的产品利润,食品安全保障,越来越苛刻的法规要求和全球化的市场与品牌维持的重要性对乳品行业的企业提出了更高的要求,实施 MES将是企业唯一的出路. 自从“十一五”制造业信息化为MES正 ...
- SRF之日志和异常
日志: 日志功能采用log4net实现 log4配置文件在站点目录下的log4net.config. 调用log4写日志的代码如下: log4net.ILog logger = log4net.Log ...
- Python学习教程(learning Python)--3 Python分支结构和布尔逻辑
本章节主要探讨研究Python下的分支选择结构程序设计问题. if语句用来检验一个条件, 如果 条件为真,我们运行一块语句(称为 if-块 ), 否则 我们处理另外一块语句(称为 else-块 ) ...
- 编译android程序时DEX过程出现错误
今天编译高级设置时出现了错误,这好坑爹啊~ 于是我开始检查代码,发现代码没有错误啊,然后观察MAKE的步骤才发现是DEX时出现了问题!! 下面是错误的LOG: Information:Using ja ...
- DoubanFm之设计模式(一)
前两版DoubanFm写的太戳,第一版可以忽略,当是熟悉WP手机的一些API.. 第二版用了比较多的依赖注入,熟悉了Messenger,过后越写越大,感觉不对,赶快打住..现在开始好好思考各模块了. ...
- java的基本数据类型特征
java的数据类型分为基本数据类型和引用数据类型. 基本数据类型分为数值型.字符型(char).布尔型(boolean) 数值型变量 1.整数型 类型 占用存储空间 表示范围 byte 1字节Byte ...
- Linux基础 30分钟GDB调试快速突破
引言 Linus心灵鸡汤 在*nix开发中有道卡叫gdb调试,不管你怎么搞. 它依然在那丝毫不会松动.今天致敬一个 活着的传奇 Linus Torvalds Unix 始于上个世纪60年代,在70年代 ...
- ORACLE-RAC-11G-R2_INSTALL
ORACLE 11.2.0.3 RAC INSTALL 20 ...
- Android 创建单例模式的几种方法
java模式之单例模式:单例模式确保一个类只有一个实例,自行提供这个实例并向整个系统提供这个实例.特点:1,一个类只能有一个实例2,自己创建这个实例3,整个系统都要使用这个实例 Singleton模式 ...