解答有关REST的十点疑惑

在了解过REST之后,你肯定很想知道这个概念在你的实际应用当中究竟能派上多大用场。而且,假如你已经熟悉另一套完全不同的架构手法的话,那么你担心“REST或REST式HTTP(RESTful HTTP),是否真的能在实践中派上用场,还是在介绍性的、‘Hello, World’级场景以外就不灵光了”是很正常的。我将在本文解答人们——尤其是那些深谙基于SOAP/WSDL的Web服务架构手法的人——开始研究REST时容易产生的关于REST的十点疑惑。

1.REST也许适用于CRUD,但并不适用于“真实的”业务逻辑

这是那些对REST的好处持怀疑态度的人最常见的反应。毕竟,要是你只能create/read/update/delete,那你如何表达更复杂的应用语义呢?我已经在本系列介绍性的文章中探讨过这些被大家所关心的问题了,不过这方面绝对值得进一步讨论。

首先,HTTP动词(verbs)——GET、PUT、POST和DELETE——跟数据库的CRUD操作并不是一一对应的。例如,POST和PUT都可用于创建新资源,它们的区别在于:PUT请求是由客户端决定(被创建或更新的)资源的URI;而POST请求是向一个“集合(collection)”或 “工厂(factory)”资源发出的,是由服务器来指派URI的。不过无论怎样,我们回到那个问题:如何应付更复杂的业务逻辑呢?

任何返回一个结果 c 的计算 calc(a, b),都可被转换为一个标识其结果的URI——例如 x = calc(2,3) 可被转换为http://example.com/calculation?a=2&b=3。初看,这仿佛是完全错误的REST式HTTP的用法——我们应当用URIs来标识资源(resources)而不是操作(operations),不是吗?没错,其实你就是这么做的:http://example.com/sum?augend=2&addend=3 标识的是一个资源,即2加3的结果。在这一特定的(显然是精心设计的)示例中,用GET来获取计算结果可能是个好主意——毕竟它是可缓存的(cacheable),你可以引用它,而且该计算多半是安全的(safe)且代价很小的。

当然,在许多(即便称不上大多数)情况下,用GET来执行计算也许是会犯错的。别忘了,GET应当是一个“安全的(safe)”操作,也就是说,假如客户端只是通过发出GET请求来跟随一个链接,那么它不承担任何义务(比如因使用你的服务而向你付费)或责任。所以,在许多其他情况下,“通过POST请求向服务器提供输入数据、以便服务器新建一个资源”是更合适的做法。服务器在响应该POST请求时,可以给出结果的URI (而且有可能发起一个重定向把你转向过去)。这个结果接下来便可被重用、被加入书签、在获取时被缓存等等。你基本上可以将这一模型推广应用到任何产生结果的操作——这涵盖几乎你所能想到的所有操作。

2.没有正式的契约与描述语言

从RPC到CORBA,从DCOM到Web服务,我们已习惯于拥有一个“列出操作、名称及输入输出参数类型”的接口描述(interface description)了。没有接口描述语言的话,REST怎么用呢?

就这一被十分频繁问到的问题,有三点答复。

首先,假如你决定用XML(这是很普遍的做法)来配合REST式HTTP的话,那么各种现有的XML模式语言(schema languages)(如DTD、XML Schema、RELAX NG、Schematron等) 仍旧可供你使用。可以说,一个用WSDL描述的东西,常常有95%的内容并不是跟WSDL相关、而是跟你定义的XML Schema复杂类型(complex types)相关的。WSDL所增加的,大部分是有关操作(operations)及其名称的——对于REST的统一接口(uniform interface)来说,描述这些是颇为无趣的,因为GET、PUT、POST和DELETE就是你所能使用的全部操作了。关于XML Schema的使用,这意味着,即便你依赖于一个REST式接口,你仍旧可使用你所偏爱的数据绑定工具(假如刚好你有的话)来为你偏爱的语言生成数据绑定代码。(回答还没结束,见下。)

第二,问问你自己需要描述做什么。最常见(尽管并非唯一)的用例(use case)是:描述被用来给接口生成桩(stubs)和骨架(skeletons)代码。它通常不是文档(documentation),因为WSDL格式的描述并不是告诉你操作的语义——它只是告诉你操作的名称。你得通过一些人类可读的文档来了解如何调用它。典型的REST做法是,你应提供HTML格式的文档,其中可能包含指向你的资源的直接链接(direct links)。如果你采取提供多个表示(multiple representations)的做法的话,那么你可以真正拥有自文档化的(self-documenting)资源——你只要在浏览器中对一个资源做 HTTP GET请求,就可以得到一个HTML文档,其中不但包含数据,还包含你可以对它执行的操作(HTTP动词)的列表以及它接受和返回的内容类型(content types)。

最后,假如你坚持为你的REST式服务(RESTful service)使用描述语言,那么你可以使用WADL(Web Application Description Language,Web应用描述语言),或适当地使用WSDL 2.0(其制定者声称它也可以描述REST式服务)。不过,WADL和WSDL 2在描述超媒体(hypermedia)方面均无帮助——而且考虑到这是REST的核心方面之一,我不太确信它们是否充分有用。

3.谁真会把他们应用中如此多的实现细节暴露出来?

另一个普遍关心的问题是,资源太低层(low-level),暴露了那些不应暴露出来的实现细节。说到底,这不就把“按有意义的方式来运用资源”的担子加到客户端(消费者)的身上了吗?

简单的回答是:不。一个资源的GET、PUT或其他方法的实现,可以跟一个“服务”或RPC操作的实现复杂程度相当。应用REST设计原则,并不是说你必须把下层数据模型(underlying data model)中的各项暴露出来——它只意味着,你采用以数据为中心的(data-centric)方式、而不是以操作为中心的(operation-centric)方式把业务逻辑暴露出来。

一个相关的关切是,不支持对资源的直接访问将增加安全性。这是由“通过隐匿得到安全(security by obscurity)”这条陈旧的谬论得出的结论。人们可以这样反驳:其实恰恰相反,如果你隐瞒你通过特定于应用的协议访问哪些资源,你将无法利用基础设施(infrastructure)来保护它们。通过为有意义的资源指派单独的URI,你可以利用Apache的安全规则(以及重写逻辑、日志和统计等)对不同资源采取不同处理。把这些明确化了,你的安全性将得到提升,而不是降低。

时间: 2024-10-28 12:37:09

解答有关REST的十点疑惑的相关文章

白话REST-识别真假REST

大家对REST的认识?          谈到REST大家的第一印象就是通过http协议的GET,POST,DELETE,PUT方法实现对url资源的CRUD(创建.读取.更新和删除)操作.比如http://www.aizher.com/c2/(读取)仍然保持为 [GET] http://www.aizher.com/c2/http://www.aizher.com/c2/create(创建)改为 [POST] http://www.aizher.com/c2/http://www.aizher

优质博文list(分布式文件系统/存储/搜索)

 转载请注明出处:http://blog.csdn.net/zbf8441372 把一些好的,有用的博文搜集在这里,陆续更新,主题大都是涉及到分布式系统,文件和存储之类,还有云计算,包括一些强大的,热门的open-source,包括NoSQL生态系统,Hadoop家族,lucene全文搜索工具,一些Apache项目等等.另外一些比较好的站点和博客地址,可以拓展阅读. 20. REST相关 深入浅出REST 对REST的比较通俗,全面的基本介绍 解答有关REST的十点疑惑 19. 分布式系统工程实

设计好用户教育,如何告诉用户想了解的信息

文章描述:其实用户教育的设计都是我们在平常设计中习以为常的小部分的添加或者再次利用,而设计好用户教育的关键是做为设计师的你能够明白,用户当前需要了解怎样的信息以及如何告诉用户这些信息.这就是手机产品"一见钟情"的小秘密. 随着手机硬件的更新换代,应用功能逐渐丰富,交互过程也逐渐变的繁杂起来.因此,一款手机应用是否能让用户眼前一亮,除了它本身成功的产品架构设计和市场运营外,简单清晰的用户教育也为其起到了画龙点睛的作用.用户教育是什么呢? 它既不是条条款款的使用说明,也不是枯燥无味的用户需

迅雷会员钻石子帐号使用和激活方法

  小编在各大贴吧上面经常可以看见大家提问有关于迅雷钻石会员子账号的激活跟使用的一些问题,在这里,就来给大家做一个问题汇总介绍,希望能帮助到这一部分的朋友,解答大家心目中的疑惑哦,如果你有更好的补充,请在下面直接留言谈论即可. 子账号使用流程: 1.进入迅雷会员官网页面: http://vip.xunlei.com/vip_service/index.html 2.在钻石会员特权页面找到子帐号的入口即可进入进行设置操作 子账号使用规则说明: 1.只有迅雷钻石会员才有激活子帐号的权限,钻石VIP3

Spark 实时计算整合案例

1.概述 最近有同学问道,除了使用 Storm 充当实时计算的模型外,还有木有其他的方式来实现实时计算的业务.了解到,在使用 Storm 时,需要编写基于编程语言的代码.比如,要实现一个流水指标的统计,需要去编写相应的业务代码,能不能有一种简便的方式来实现这一需求.在解答了该同学的疑惑后,整理了该实现方案的一个案例,供后面的同学学习参考. 2.内容 实现该方案,整体的流程是不变的,我这里只是替换了其计算模型,将 Storm 替换为 Spark,原先的数据收集,存储依然可以保留. 2.1 Spar

Weex 近 4 个月的开源之路

文章作者:勾股 阿里巴巴高级技术专家 仅从我个人角度跟大家分享一下自己参与 Weex 开源这几个月以来的感受,中间可能会有写观点是偏颇的或者片面的,希望大家指正,另外不论怎样,这些都是我心里真实的想法和感受. 为什么选择开源 有两个关键字:加速.共赢 我们提出来要开源的时候,在网上被很多人质疑过.有人质疑说这是个"KPI项目",作者折腾完要"弃坑"了,所以就把它开源了:也有人质疑它的成色,也有人质疑"电商"的标签,是不是只有你们阿里用得到,别人都

翻转课堂教学感受调查

数据结构课程结束,进行了教学感受调查,记录并公布如下. 开始时间:2015-12-22 结束时间:2016-1-17 样本总数:78 份 原始数据来源:http://www.sojump.com 本报告包含样本数量:78份 第1题 如果再学一次数据结构,你希望老师采用____ [单选题] 第2题 对于翻转课堂中,你有切身体会的好处有__ [多选题] 第3题 关于课前视频,根据对同学们学习需求的分析,采取了精讲的策略.你认为_ [单选题] 第4题 总体而言,课前视频___ [多选题] 第5题 对于

使用EasyUI Tree异步加载JSON数据 生成树

这几天因为工作需要,要做一个支持无限级的菜单. 我也是菜鸟一只,能想到的东西不多,所以用了Easy UI的tree组件. 不得不说,easyui确实很强大.  因为是无限级菜单,数据量可能有点大,所以考虑采用异步加载. 但是因为后台默认传来的数据是 一个实体,所以又在后台进行了JSON字符串拼接. 最后,在网上找了N多代码,然后又去问了好几个群里的网友,终于搞出来这个小东西.    一.HTML部分代码 <div id="categoryChooseDiv" title=&quo

类字面常量和静态代码执行顺序

今天看Java编程思想的时候对一个程序百思不得其解,完全弄明白花了不少功夫,弄明白后收获不少,这里还要感谢慕课网的一位讲师Qiujuer,非常感谢这位大神平时对我的耐心指导,这让我进步很快,这位大神每天在百忙之中还抽出大量的时间解答群员的各种疑惑,实在令人钦佩,这是他在慕课网的课程http://www.imooc.com/learn/741,质量很高,看了受益匪浅.这是大神的Github:https://github.com/qiujuer 神作颇多,值得关注.好了,其他话就不说了,先上代码: