InfoQ:HTTP1.1规范中给出的动词对于设计RESTful API够用吗?您在实际项目中会扩展自己的动词吗?在什么情况下需要扩展?
李锟:这个问题取决于设计者如何看待和设计资源。如果资源抽象做的很好,对于某个资源的任何操作,通常都能够映射到CRUD四个类别
中。CRUD四个类别对于操作资源来说,绝大多数情况下是完备的。HTTP的GET/POST/PUT/DELETE四个方法,对于CRUD四个类别的操
作来说是足够的,映射关系是Create-POST/Retrieve-GET/Update-PUT/Delete-DELETE。
我们通常不会选择创建自己的动词,这样做对于客户端开发者来说,需要更多的学习成本。如果在资源上定义的操作过多,我们会选择拆分出更多的资源。
李建业:一般是够用的,有时一些“不够用”的场景是由于我们没有设计出合理的资源,比如批量操作。但是,正如之前所说的那样,对于某
些内部的、传统的(因此模型稳定且已知)系统,API提供者和调用者会有自已的固定动词表,此时没必要拘泥。另外,我不建议扩展动词,一旦扩展了动词,其
实已经破坏了我之前说的*“尽可能少的先验信息”*,那么,扩展动词和重新设计动词的成本差别不大。基于这个考虑,我建议尽可能保持动词不变,除非你想重新设计动词表。
丁雪丰:一般情况下,常用的HTTP动词是够用的,并没有出现一定要自己扩展动词的情况。其实,最常用的也就是GET、POST、
DELETE和PUT,而HEAD、OPTIONS、TRACE则基本用不太到。如果出现一时找不到合适的动词,安全幂等的操作用GET,其他都可以用
POST,在设计资源时稍加考虑即可。
马钧:在我的实际项目中,只用到了POST,PUT,DELETE,GET这四个动词。
InfoQ:今年5月份发布的JAX-RS 2.0规范对于RSTfulAPI的设计最有价值的特性是哪个(些)? 它(们)用于解决什么问题?
李锟:REST开发框架RESTEasy项目负责人Bill Burke,去年写了一篇文章介绍JAX-RS 2.0。
我同意Bill在文章中的观点,在JAX-RS 2.0增加的内容中,最重要的三部分为:
a) Client API——用来规范化JAX-RS客户端的开发方式。
b) Server-side Asynchronous HTTP——用来实现服务器端推送功能,而不需要依靠低效的轮询方式。
c) Filters and Interceptors——用来分离关注点,将鉴权、日志等逻辑与业务逻辑分离开,更好地实现代码重用。
这三部分的内容对于开发者来说都很有用。遵循JAX-RS规范做开发,可以确保服务器端以及客户端代码的可移植性。
李建业:我个人关注异步API这部分,主要是因为流式服务将会越来越多,那将大量需要这类支持。
InfoQ:能否为InfoQ的读者推荐一款实用的RESTful API开发框架,并说明您的推介理由。
李锟:这个问题我就不详细回答了。不同的编程语言有不同的REST开发框架,对于REST的支持程度也不同。开发RESTful
API的需求范围很广,可选择的开发框架的范围也很广。保持多样性是繁荣生态环境的基础。像Java就有支持JAX-RS规范的Jersey、
RESTEasy、Restlet、Apache CXF,和不支持JAX-RS规范的Spring
MVC等等很多框架。这些框架目前都做的不错。我对框架的选择没有倾向性。RESTful
API设计的最佳实践应该是通用的,而不是必须依赖某种特定的开发框架。
李建业:不好意思,这个我不太重视,没法推荐,不过我可以解释一下为什么对RESTful API框架不感冒的原因。
REST作为一个架构风格,对我们的系统开发有很大影响,但是这些影响一般是针对架构(例如状态无关)或者设计(例如资源识别)上的,所以一旦涉及
到具体实现,主要工作就基本结束了,此时开发框架能做的事也就只有简化编程了(相较而言,有的框架还能起到引导设计的作用),而由于RESTful会抽象
动词,所以实现层面中和API规范相关的工作本来就不多,那么框架的价值就更小了。
当然,我们也不可能直接基于servlet/rakc/wsgi来开发,不过一般的编程语言都会提供一些简单的url
route/match策略,我们使用这些就足够了。另外,有些框架能帮我们生成全部的动词支持,但这也未必是好事,我一般倾向于按需实现——用到了再支
持,这就更不需要太关注开发框架对RESTful的支持了。
丁雪丰:由于本人是Spring的拥护者,工作中也一直在使用Spring,所以在选择框架时会更多地倾向Spring
MVC(并不是说别的框架不好,这里有些个人主观的成份)。如果一定要选择其他框架,也要选择能够方便与Spring集成的框架。如果在项目中已经使用了
Spring,那么没有什么理由不选择Spring MVC,鉴于目前Spring在各种项目中的高出镜率,相信一般情况下都会选择Spring
MVC。
REST的成熟度模型中,第三层就是HATEOAS,Spring目前还提供了Spring Hateoas子项目,对链接、资源等方面的支持都做了一定的增强。
马钧:我目前在实际项目中使用的是Spray,这是一个开源的 REST/HTTP 工具包和底层网络 IO 包,基于 Scala 和 Akka 构建。轻量级、异步、非堵塞、基于 actor 模式、模块化和可测试是Spray的特点。
InfoQ:HTTP2.0规范正在制定当中,您对它的期待是什么?
李锟:我的期待包括两个方面:应该做的和不应该做的。
HTTP/2.0规范应该做的:
- 与HTTP/1.1协议保持兼容。兼容的含义是说两者可以并存,客户端应用可以根据服务器端的能力,自由地选择使用HTTP/2.0还是HTTP/1.1,而且选择过程对应用来说是透明的。
- 改进HTTP协议(作为资源的统一接口)之中操作语义表达方式的语法,提高网络传输效率。
- 更好地模块化,这样HTTP/2.0协议的实现能够更好地模块化。应用程序可根据需要选择适当的模块,而不是要么全有、要么全无。
- 废弃掉HTTP/1.1协议中一些很少有人用到的部分,例如采用管道(pipelining)方式发送请求。
- 增加更多的动词,以适应除CRUD之外的其他场景。
HTTP/2.0规范不应该做的:
- HTTP/2.0协议不应该把底层的数据加密机制(即SSL)作为必选项。
- HTTP/2.0协议不应该背离REST架构风格的约束,尤其是要确保操作语义对于中间组件的可见性。
在上面这两个方面,Roy Fileidng曾经与SPDY协议设计者Mike Belshe发生过激烈争论,详情请看:Roy Fielding谈Google SPDY协议
李建业:对此规范关注不多,不知道会不会有对于流的支持,目前我所知道的只有chunk方式进行简单的支持,但是真正的流需要区分数据通道和控制通道——哪怕是逻辑上的区分,这样就直接对REST风格产生了很大冲击,考虑到流式服务在未来的发展潜力,我特别期待业界在这方面有所进展。
丁雪丰:HTTP 2.0很大程度上是借鉴了Google的SPDY,就我而言,首先,希望这个规范能做到与HTTP
1.1的兼容,使用者如果只认识1.1,那么2.0能优雅“降级”;其次,希望2.0能带来更好的性能,SPDY在这方面还是有所改进的,希望HTTP
2.0能再接再厉;最后,希望这个规范能在最终定稿时附带一个最佳实践,正确引导人们合理地使用HTTP 2.0。
马钧:没研究过,估计即使出来,1.1还有很长的生命周期,不会很快被取代。
关于专家们
李锟:从2003年开始尝试Ajax开发,意识到这种开发方式的优点后,次年(2004年)在知名技术论坛JavaEye上与技术爱
好者深入讨论过相关问题。他也是轻量级Java开发框架的拥护者,曾参与JavaEye论坛组织的《J2EE Development without
EJB》一书的翻译。在2007年Ruby on Rails
1.2版支持REST开发之后,他对搞清楚REST的来龙去脉产生了浓厚兴趣,同年组织翻译了Roy T.
Fielding的博士论文《Architectural Styles and the Design of Network-based
Software
Architectures》(中文版名为《架构风格与基于网络的软件架构设计》)。在2011年又翻译了《REST实战》一书,目前仍然致力于在国内普
及对于REST架构风格的深入理解,以及相关实战经验的交流。目前主要感兴趣的技术领域包括DDD、DSL、SOA、REST。
李建业:2002年毕业,之后一直从事软件开发,涉及办公自动化、电信网管/增值业务系统以及互联网;2009年12月加入淘宝的广
告应用开发团队;从
2011年底开始,关注软件研发本身,涉及运维和测试相关工作,目前关注持续集成。李建业还经常受邀出席一些技术大会并发表主题演讲,比如
InfoQ,Ruby大会等。
丁雪丰:一线攻城师一枚,InfoQ中文站小编,常年混迹于各种社区,业余时间写作翻译、汉化软件,《RESTfulWebServices Cookbook中文版》、《Spring攻略》等多部图书的译者。
马钧:全端程序员,15年以上多种程序编程经验,爱好开源软件,积极参加各类社区活动,《REST实战》等技术图书的译者。 |