摘要:REST——表征状态转移,由于REST模式的Web服务更加简洁,越来越多的Web服务开始采用REST风格设计和实现。例如,Amazon.com提供接近REST风格的Web服务进行图书查找;雅虎提供的Web服务也是REST风格的。

本文我们将讨论REST,它定义了一组体系架构原则,您可以根据这些原则设计以系统资源为中心的Web服务,这是一个非常容易让人误解的概念。本文主要是写给那些想设计WebService API但却对REST没有十分清晰认识的开发者们。在本文最后会附上一些资源供大家学习,这些资源讲解非常详细。

什么是REST

表征状态转移(Representional State Transfer),是Roy Fielding( HTTP规范的主要编写者之一)博士在2000年他的博士论文中提出来的一种软件架构风格。它并不是一个标准,而是通过表征(Representional )来描述传输状态的一种原则。其宗旨是从资源的角度来观察整个网络,分布在各处的资源由URI确定,而客户端的应用通过URI来获取资源的表征。获得这些表征致使这些应用程序转变了其状态。随着不断获取资源的表征,客户端应用不断地在转变着其状态。

目前在三种主流的Web服务实现方案中,因为REST模式的Web服务与复杂的SOAP和XML-RPC相对比,更加简洁,越来越多的Web服务开始采用REST风格设计和实现。例如,Amazon.com提供接近REST风格的Web服务进行图书查找;雅虎提供的Web服务也是REST风格的。

让我们来思考一下:

Marcus是一个农民,他有4头牛,12只鸡和3头奶牛。他现在模拟一个REST API,而我是客户端。如果我想用REST来请求当前的农场状态,我仅会问:“State?”Marcus会回答:“4头猪、12只鸡、3头奶牛”。

这是REST最简单的一个例子。Marcus使用表征来传输农场状态。表征的句子很简单:“4头猪、12只鸡、3头奶牛”。

再往下看,看我如何让Marcus用REST方式添加2头奶牛?

按照常理,可以会这样说:Marcus,请在农场你再添加2头奶牛。难道这就是REST方式吗?难道就是通过这样的表征来传输状态的吗?不是的!这是一个远程过程调用,过程是给农场添加2头奶牛。

Marcus很愤怒地响应到:“400,Bad Request”,你到底是什么意思?

所以,让我们重新来一次。我们怎样做到REST方式呢?该怎样重新表征呢?它应该是4头猪、12只鸡、3头奶牛。好,让我们再次重新表征……

我:“Marcus,……4头猪、12只鸡、5奶牛!”

Marcus:“好的”。

我:“Marcus,现在是什么状态?”

Marcus:“4头猪、12只鸡、5头奶牛”。

我:“好!”

看到了吗?就这样简单。

为什么RPC也不够好?

从逻辑角度来看,为什么会更加青睐REST而不是RPC(Remote Procedure Call,远程过程调用 ),因为它极大的降低了我们沟通的复杂度,通过把表征作为唯一的沟通的方式。无需去讨论过程(添加一头牛?增加一种动物类型?给鸡的数量翻倍还是卖掉所有猪?)我们只需讨论表征,并且使用这个表征来达到我们想要的目标,很简单,不是吗?我不希望和Marcus的沟通失败,因为我们彼此的理解过程会不一样,所以只需要知道最后的状态就行。但这仅仅是创建RPC会产生许多问题之一。如果你使用RPC,你需要设计一些程序嵌入到某种结构中。这种结构需要存储参数、错误的代码、返回值等。我已经看到许多公司这样做,他们设计自己的RPC-结构来实现客户端与服务器端的交互,但却产生许多问题。你为什么要这么做?为什么要创建自己的RPC-结构?这样做的好处是?倘若我想要让应用程序使用许多WebService,并且这些WebService带有多个RPC-格式属性?那么我不得不去开发一些类似这样的东西:

如果你们真的需要RPC,至少要选择一个类似SOAP的标准。

但SOAP也很糟糕

即使RPC的标准真的很令人痛苦,但我不得不承认ACID事务,一个完整的标准化服务描述性语言SOAP(Simple Object Access Protocol,简单对象访问协议)在某些环境下表现的还不错。尽管如此,SOAP产品的性能开销很大,它是一个巨大的性能杀手。虽然REST不是一个标准,但在实现RESTful Web服务时可以使用其他各种标准(比如HTTP、URL、XML、PNG等)。

Session更邪恶

你无需Session!但有人会说:“我想要保存用户购物车里的商品,所以我必须要Session!”不,这样想是错误的!即使没有Session,你也可以做你任何你想做的事情。你可以只需在URL里封装购物车信息,或者为购物车创建另一个资源,比如“/carts/5235”。

不需要与客户端进行会话,通过这些操作(指在URL里封装购物车信息,或者为购物车创建另一个资源,比如“/carts/5235”)后,客户端向服务器发出请求后,哪怕你在服务器上执行卸载平台和操作系统、拆除服务器硬件、重新组装服务器、重新安装操作系统、平台、应用程序备份恢复操作,也不会影响客户端。

不要强迫客户端保存状态,这样做不仅复杂,而且还会带来许多问题,你应该从你的Web应用程序里删除有状态的东西。

不要重造超媒体

目前,超媒体已经相当普及,我提醒大家,不要再去重新造轮子。这里已经有许多,足够你使用了:

其他资源

这里还有一些更加深入的资源供你参考使用:

(编译:张红月 责编:王果)

来自:Why REST is so important

为啥REST如此重要?的更多相关文章

  1. (视频)《快速创建网站》 4.1 为啥造软件不同于造汽车,为啥是软件就一定会有Bug - 构建开发运维一体化(DevOps)

    本文是<快速创建网站>系列的第9篇,如果你还没有看过之前的内容,建议你点击以下目录中的章节先阅读其他内容再回到本文. 访问本系列目录,请点击:http://devopshub.cn/tag ...

  2. ARM你必须知道的事儿——为啥“PC = PC + 8”?

    为啥是“PC = PC + 8”: “PC = PC + 8”其实这样写容易让人蒙了.“PC = PC + 8”真正含义应该是: 执行处代码地址 = PC - 8: 也就是说,”PC指向的地址“领先“ ...

  3. (转载)为啥我们要学习Linux

    学习Linux也有一阵子了,这过程中磕磕撞撞的,遇到了问题,也解决了一些问题,学习的路子是曲折的,想总结点啥的,让刚刚学习Linux的不会望而生畏. 为啥我们要学习Linux 技术的价值不在于这个技术 ...

  4. 为啥NSString的属性要用copy而不用retain

    之前学习生活中,知道NSString的属性要用copy而不用retain,可是不知道为啥,这两天我研究了一下,然后最终明确了. 详细原因是由于用copy比用retain安全,当是NSString的时候 ...

  5. 为啥都不用Qt Quick Controls 2呢

     为啥都不用Qt Quick Controls 2呢  https://github.com/qt/qtquickcontrols2/ 

  6. git add --all 为啥不能添加空文件夹,这样设计的初衷是

    git add --all 为啥不能添加空文件夹,这样设计的初衷是? 好多项目还得弄个假文件在空文件夹里面占位 这个算设计失误吧,见 https://git.wiki.kernel.org/index ...

  7. 一个网友写的栈,问为啥不能迭代。具有__iter__ 和next方法的对象叫迭代器-七七巴巴黄页网

    一个网友写的栈,问为啥不能迭代.具有__iter__ 和next方法的对象叫迭代器-七七巴巴黄页网 一个网友写的栈,问为啥不能迭代.具有__iter__ 和next方法的对象叫迭代器 python视频 ...

  8. javascript 为啥不用instanceof检测数组,这里有一个示例坑

    前些天写js遇到了一个instanceof的坑,我们的页面中有一个iframe,我在index页面中计算得到了一个array,然后需要传递到Flight页面 这个嵌套的iframe中的一个函数(Sea ...

  9. arm的编译器里已经有C标准库的lib包了,android为啥还要自己再实现呢

    arm的编译器里已经有C标准库的lib包了,android为啥还要自己再实现呢 google自己搞的bionic libc来替代glibc想来是有原因的,本来glibc也是lgpl,应该也没有版权问题 ...

  10. 分析下为什么spring 整合mybatis后为啥用不上session缓存

    因为一直用spring整合了mybatis,所以很少用到mybatis的session缓存. 习惯是本地缓存自己用map写或者引入第三方的本地缓存框架ehcache,Guava 所以提出来纠结下 实验 ...

随机推荐

  1. 结对作业(1)----基于GUI的四则运算

    小伙伴:201421123031 余洋 201421123044  潘志坚  题目要求: 我们在个人作业1中,用各种语言实现了一个命令行的四则运算小程序.进一步,本次要求把这个程序做成GUI(可以是W ...

  2. 201521123049 《JAVA程序设计》 第8周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结集合与泛型相关内容. 2. 书面作业 本次作业题集集合 1.List中指定元素的删除(题目4-1) 1.1 实验总结 public ...

  3. 201521123122 《java程序设计》 第三周学习总结

    1. 本章学习总结 你对于本章知识的学习总结 链接点击此处 2. 书面作业 代码阅读 public class Test1 { private int i = 1;//这行不能修改 private s ...

  4. 201521123077 《Java程序设计》第9周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常相关内容. 异常分为uncheckedException和checkedException checkedException 继 ...

  5. Java课设 彩票购买抽奖程序 个人博客

    一.团队课程设计博客链接 http://www.cnblogs.com/lyq063/p/7072507.html 二.自己的代码提交记录截图 三.自己负责模块或任务详细说明 用户注册信息的存储和登录 ...

  6. Hyperledger Fabric 1.0 从零开始(三)——环境构建(内网/准离线)

    有公网环境的服务器可以直接看 Hyperledger Fabric 1.0 从零开始(二)--环境构建(公网) ,本篇内容与上篇相似,只不过环境搭建需要在内网下,也就是网络被限制的情况下. 1:环境构 ...

  7. panda库------对数据进行操作---合并,转换,拼接

    >>> frame2 addr age name 0 beijing 12 zhang 1 shanghai 24 li 2 hangzhou 24 cao >>> ...

  8. springmvc03-异常处理-静态文件

    1,一个简单的登录 login.jsp页面 <%@ page language="java" contentType="text/html; charset=UTF ...

  9. 转换时间对象和字符串对象&添加时间

    /* *基本思路,将字符串时间转化为时间对象,通过毫秒数来加减时间,然后在转化为字符串输出 */ //转化字符时间yy-mm-dd hh:mm:ss 为时间对象   使用split进行字符串的分割,取 ...

  10. 云计算之openstack ocata 项目搭建详细方法

    之前写过一篇<openstack mitaka 配置详解>然而最近使用发现阿里不再提供m版本的源,所以最近又开始学习ocata版本,并进行总结,写下如下文档 OpenStack ocata ...