SOA之(5)——REST的SOA(SOA with REST)概念
引自:http://www.cnblogs.com/richaaaard/p/5006432.html
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 服务端通常通过资源表述不同的后缀形式提供不同的内容格式(只是一个best practice而不是标准)
- GET /resource.html
- GET /resource.xml
- GET /resource.json
- 异常处理(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标准)