- 浏览: 117774 次
- 来自: ...
文章分类
最新评论
关于REST, 经常容易引起困惑的一个问题是:在 Machine-to-machine 的 REST 应用中, 客户端怎么可能在没有任何预先知识的情况下就能跟随服务器端返回的超文本来自适应的将应用程序逻辑进行下去?
答案是不可能 . Client端必须提前了解足够的 server端返回的超文本的知识 , 才能跟随其中的指示将逻辑进行下去 . 那跟 SOAP, WSDL之类的又有啥区别 ? 答案在于 REST 要求的 “足够知识 ”要远远弱于 WSDL对服务接口定义的约束 , 其灵活性则高于 WSDL. 毕竟 , REST 架构风格着眼于生命周期较长的 , 不断演化的 , 跨组织边界的应用程序 . 可以用来满足 HATEOAS这个 REST约束的武器就是 Media Type: 扩展已有的 Media Type, 发明新的 Media Type, 并在合适的范围内标准化
来看两个例子 .
Web的成功与其说是 HTTP的成功 , 不如说是 HTML的成功 , 或者说 text/html这种 Media Type的成功 . HTML定义了一组有限的 , 标准化的 , 特定领域的标签 . 所有的 HTML客户端都能理解并按照自己的能力渲染出 Web服务器返回的任何合法的 HTML. 从全功能的 Chrome/FireFox /Safari/IE, 到只是显示文本的 lynx, 到资源受限环境下如手机中的各种浏览器 , 都能将多姿多彩的 Web呈现给最终用户 , 并引导他们进行下一步交互
最经常被拿来作为 machine-to-machine REST 应用成功案例的则是 RSS/ATOM. 这族标准定义了新的 Media Type, application/rss+xml , application/atom+xml . 不出意外的 , 这组 Media Types定义了一组有限的 , 标准化的 , 特定领域的标签 . 每一个 RSS/ATOM客户端应用都可以从某个资源的 application/rss (atom)+xml的表述开始 , 顺藤摸瓜的遍历每个感兴趣的资源 . 这些客户端都理解每一个 RSS/ATOM定义的标签 . 服务端可以自由的改变新资源的 URI/URL Template而不必担心破坏现有的 Client, 因为这些 Client并不依赖于预先设定的 URL Template, 而仅仅依赖于一个 Root的表述 , 及标准的 link relations
回到我们的问题 . 那么 REST要求的 “足够知识 ”要弱到什么程度 , 才能既使客户端能理解服务器给出的线索 , 又不致于耦合的太紧以致服务器和客户端无法独立演化 ? 观察上面两个例子 , 它们有以下共同特点 :
1. Response是 Well-formed ,可以被客户端解析 . 这是废话 , 除了 AI应用 , 绝大部分网络应用都得有明确定义的协议 . 但这意味着 REST 应用中也必须明确定义客户端和服务器数据交换的格式
2. Response中包含了当前上下文 ( 或资源 )相关的信息 , 但对我们这个问题来说更重要的是包含了对其它资源进行访问的线索 . 是的 , 它是用最最基本 , 最最普通的 link 来实现的 . 足够弱 . 那语义是否足够清晰到客户端能理解每一个 link, 能够选择正确的 link并知道如何访问呢 ? 我们来看看 link上都能承载啥语义 (from http://www.ietf.org/rfc/rfc5988.txt):
Link = "Link" ":" #link-value link-value = "<" URI-Reference ">" *( ";" link-param ) link-param = ( ( "rel" "=" relation-types ) | ( "anchor" "=" <"> URI-Reference <"> ) | ( "rev" "=" relation-types ) | ( "hreflang" "=" Language-Tag ) | ( "media" "=" ( MediaDesc | ( <"> MediaDesc <"> ) ) ) | ( "title" "=" quoted-string ) | ( "title*" "=" ext-value ) | ( "type" "=" ( media-type | quoted-mt ) ) | ( link-extension ) ) link-extension = ( parmname [ "=" ( ptoken | quoted-string ) ] ) | ( ext-name-star "=" ext-value ) ext-name-star = parmname "*" ; reserved for RFC2231-profiled ; extensions. Whitespace NOT ; allowed in between. ptoken = 1*ptokenchar ptokenchar = "!" | "#" | "$" | "%" | "&" | "'" | "(" | ")" | "*" | "+" | "-" | "." | "/" | DIGIT | ":" | "<" | "=" | ">" | "?" | "@" | ALPHA | "[" | "]" | "^" | "_" | "`" | "{" | "|" | "}" | "~" media-type = type-name "/" subtype-name quoted-mt = <"> media-type <"> relation-types = relation-type | <"> relation-type *( 1*SP relation-type ) <"> relation-type = reg-rel-type | ext-rel-type reg-rel-type = LOALPHA *( LOALPHA | DIGIT | "." | "-" ) ext-rel-type = URI
这里我们重点考察一下 rel 和 media-type 属性
在 ATOM(http://www.ietf.org/rfc/rfc4287.txt)里 , 缺省定义了 5种 link relations, 分别是 alternate, related, self, enclosure和 via. 标准赋予它们明确的语义 , 比如 alternate表示 link所指向的目标是当前资源的备用版本 . 客户端因此可以理解每个 link的含义 , 自动或引导用户完成后面的操作 . 如何完成?则牵扯到 media-type . 比如如果 media-type定义的是 audio/mp4,客户端则可以显示播放选项或自动播放或干脆忽略 .
这里 link以及 media-type等属性帮助形成了一个递归的过程 . 我们从某个 link开始 , 知晓它的 media-type(所谓知晓它的 media-type, 就是能理解这种 media-type定义的每一个元素的语义 ), 我们就能够得到这个 link所指向的资源以这种 media-type表现出来的一种表述 , 其中包含了其它可用的 link以及 media-type, 可以让这个过程一直继续下去 , 直到客户端觉得可以了或者服务端返回了不包含任何其它 link的表述 .
然而初始的 media-type和 link relations总是有限的 , 我们如何应对现有 media-type表达不了的语义?这就是 HTML和 RSS/ATOM例子包含的第三个要素
3. 定义领域相关的 media-type . HTML的问题域是如何表达各种显示效果 , RSS/ATOM则是如何发布信息 . media-type以及 link relations等都是可扩展的 . 我们要做的就是为我们的特定领域的应用定义扩展 , 如果现存的被标准化的元素不够用的话 . 这里有一个问题 , 就是 REST应用的范围的问题 . 如果我们的应用是面向 internet的 , 面向无数已知的未知的客户端应用的 , 则意味着我们必须尽可能标准化我们扩展的 media-type, 或者至少让它广泛接受 . 而对于企业内部以 REST架构的应用 , 我们同样面临标准化的问题 , 只不过范围可能小一点 , 至少是企业内部需要有共同接受的 media-type
前面我们看到了良好定义的 media-type是如何帮助客户应用理解 server端的 response而又不致紧密耦合服务端的实现的 . 我们需要一个企业开发的例子来验证一下我们的理解 . 比如要开发一个企业内部不同应用之间共享用户信息的应用 , 包括权限信息 , 当前可以执行的操作 , 可以访问的应用 , 以及应用之间共享的 Preference设置等 . 我们可以定义一种叫 application/vnd.tw.account+xml 的 media-type 可以有以下的片段
URL Template Considered Harmful
如果这些都实现的话 , 就可以有一个推论: URL Template不是必须的,甚至是有害的 . 它限制了服务器端的变化 . 客户应用应总是从 Root Resource开始 , 在特定 Media Type的引导下解析出其它的 URI, 给予服务程序演化的灵活性而不是按照 URL Template这种预先的知识来推算 .
用REST做过很多项目的Xu Hao 对Url template也有同样的看法:"URL template在我看来是有害的,它是一种隐含的服务器和客户端约定。此外还有一点,由于大多数URL template是用来表达state transfer的URL的,比如/xxx/approve之类的,使得客户端必须了解服务器的状态转移的细节,这在我看来是一个更大的问题。这使得客户 端和服务器的耦合变得更加紧密,同时这种风格极度鼓励服务器借由客户端来维持状态的一致性"
很多REST相关的文章都把大量的篇幅给了 HTTP, 比如 HTTP Verbs POST/GET/PUT/DELETE, HTTP Status Code等 , 而 media type着墨不多 . Xu Hao在社区中曾很多次的提起自定义Media Type, 对REST应用不多可能当时不太明白, 现在越来越多的人认识到扩展和标准化更多的 media type才能更多的发挥 REST的潜力
参考资料
http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven 尤其后面的讨论
http://www.iana.org/assignments/link-relations/link-relations.xml
发表评论
-
Architecture is layered
2004-12-11 11:57 374那天被问道软件架构师需要了解编程语言的细节吗? 呵呵,架构是 ... -
Thinking Everyday
2004-12-11 12:01 4351,编程语言的发展趋势 ... -
糟糕命名集锦
2004-12-11 16:50 5661,公交支线,如375和375 ... -
古代的软件开发 (一)
2005-02-19 16:45 6721,额外的中间层鞋子:人类发明鞋子的意义无论如何评价都不过分, ... -
访问控制 : 语言和平台
2005-03-15 19:27 608程序逻辑上的组织方式(如名称空间,包等)可以和部署时的分发 ... -
Thinking Everyday II
2005-03-17 15:11 6151, 是业务,不是技术,傻瓜 是集成,不是编程 是使用,不 ... -
内容与标准为王:下一代互联网与下一代搜索
2005-07-25 14:53 697第一代互联网混淆了真正的数据和它的表现形式,第一代搜索无法 ... -
个性与定制为王:下一代互联网和下一代门户
2005-07-28 11:28 593看一下现在我与互联网有关的生活:我有两三个常用的Web邮箱 ... -
泛型编程 vs. 面向对象
2005-08-10 14:30 804面向对象:封装(数据抽象)是基础,继承是手段,多态是目的 ... -
函数式编程 vs. 对象式编程
2005-08-10 14:44 646<<我爱我家>>有一集和平摔成了脑 ... -
用手机从ATM取钱
2005-11-21 22:49 690手机的以下两个特性,使它潜在的可能成为统一的支付和信用平 ... -
Web 3.0 : Unified Human-like Interaction
2006-01-14 16:31 696你还在到搜索引擎的主页上去搜索吗?你还登录新闻网站查询最新比赛 ... -
软件生物学
2006-01-14 16:59 644长久以来,软件的建筑学隐喻已经深入人心,可始终无法达到建筑 ... -
广义对象论
2006-01-25 15:31 681前几天本想接着以前的思维中对“3.2 Programming ... -
Thinking Everyday III
2006-03-26 14:17 7821, RAII让我告别了delete,IoC让我告别了ne ... -
简单至及的AOP和IOC
2006-03-26 14:21 654I. AOP的例子 1, Google To ... -
TDD: Tricky Driven Development
2007-05-10 07:07 587命名 测试用例的名字应该描述需求, 不要描述实现. ... -
Thinking Everyday IV
2007-05-15 04:36 5131, 实际上 C# 2.0 已经部 ... -
迭代本质论
2008-02-14 13:58 624新年伊始, 可能你又要制定一些计划了, 实际上, 你的生活在开 ... -
建筑的永恒之道
2004-08-10 18:31 6462,质 这种特质是任 ...
相关推荐
Build an enterprise application using Silverlight and WPF, taking advantage of the powerful MVVM pattern, with this book and e-book Discover the evolution of presentation patterns-by example-and see...
WordPress Complete_ set up, customize, and market your blog.pdf
Dundas Chart for ASP.NET Enterprise Edition includes many advanced features including: formula support, data grouping, data filtering and advanced chart types. Dundas Chart for .NET is the ...
Sap HaNa 数据库链接 jar包。可自定义Maven坐标 添加到私有库 ...reconnect=true¤tschema=CUSTOMIZE #jdbc.username=**** #jdbc.password=***** #hibernate.dialect=org.hibernate.dialect.SAPDBDialect
Customize Rules 使用附件中的 myrules 中的内容覆盖 Customize 的内容然后保存
For your next project on GitHub, take advantage of the service’s powerful API to meet your unique development requirements.... GitHub Enterprise Appendix B. Ruby, NodeJS, (and the Shell) at GitHub
微软出版社09年新书,供有需要的人下载... The alliance between Microsoft and SAP has opened up many ways for .NET developers to use familiar skills and tools to connect with and customize SAP applications.
• Learn how to declare, instantiate, and customize Swift object types: enums, structs, and classes • Discover powerful Swift features such as protocols and generics • Catch up on Swift 3 ...
VCL Layout Control - How to Create and Customize a Simple Layout [720p]
These will bring you sky to life and offer plenty options to customize. Clouds performance is optimized by using techs like temporal reprojection and LOD system. In addition there are also fast flat ...
An indicator view providing you more freedom to control and customize it.zip,An indicator view providing you more freedom to control and customize it.一个魔性的菊花控件,助你摆脱系统菊花的各种烦恼
What you'll learn Key Spring Framework fundamentals How to use the ...Types How to customize your website What isand how to use the Spring Web Flow framework How to test your Spring MVC applications How...
- **Creating Basic and Complex Content Types**: PowerShell scripts can be used to create and configure both basic and complex content types, including document sets and publishing pages. - **...
MCE More Customize 是一款强大的媒体中心调整工具。微软的 Windows XP 中有一个特殊的版本,Media Center Edition(简称MCE),该版本除了拥有普通XP的功能外,还附带了媒体中心(Media Center)模块。使用媒体中心...
Learn how to declare, instantiate, and customize Swift object types—enums, structs, and classes Discover powerful Swift features such as protocols and generics Catch up on Swift 2.0 innovations: ...
Learn how to use familiar Microsoft ... The alliance between Microsoft and SAP has opened up many ways for .NET developers to use familiar skills and tools to connect with and customize SAP applications.
The last chapters of the book are particularly exciting, and discuss the Material Design library for Angular and the ability to customize graphics with Scalable Vector Graphics (SVG) and HTML5.
《前端开源库 Customize Engine Handlebars 深度解析》 在现代前端开发中,自定义引擎扮演着重要的角色,它们允许开发者根据特定需求定制化处理模板、数据和逻辑。其中,“customize-engine-handlebars”是一个专注...
named WekaPreprocess.pch and a precompiled types file named StdAfx.obj. ///////////////////////////////////////////////////////////////////////////// Other notes: AppWizard uses "TODO:" comments to...