理解RESTful架构


刚刚读了一篇博文,关于RESTful架构的理解。觉得讲得不错,作一下笔记。

原文链接:http://www.ruanyifeng.com/blog/2011/09/restful.html

REST的全称为Representational State Transfer

表现层状态的转化。

实际上这句话省略了一个主语,就是resource。

资源的表现层状态的转化。

资源是一种信息实体,它可以有多种外在的表现形式,我们把资源具体呈现出来的形式,叫做它的表现层。

互联网通讯的HTTP协议,是一个无状态协议。如果客户端想要操作服务器,必须通过某种手段,让服务端发生状态转化,这种转化是建立在表现层之上的,所以就是表现层状态转化。

HTTP协议里有四个表示操作方式的动词:GET,POST,PUT,DELETE。

GET用于获取资源

POST用于新建资源(也可用于更新资源)

PUT用于更新资源

DELETE用于删除资源。

设计误区

URI代表的是一种资源实体,客户端与服务端之间,传递这种资源的表现层。

所以,URI中不应包含动词。动词应该放在HTTP协议中。

比如,某个URI是/posts/show/1其中show是动词,这个URI就设计错了。应该用GET表示show这个动作,URI应该写成/posts/1

如果一些动作是HTTP那四个动词表示不了的,那应该把动作做成一种资源。比如网上汇款,从账户1向帐户2汇款500元。

POST /accounts/1/transfer/500/to/2

正确的写法应把transfer改为名词transaction。把具体的信息写在post数据里。资源不能是动词,但可以是一种服务。

POST /transaction

from=1&to=2&amount=500.00

 

需要指出,HTTP的四种动作中。GET,PUT,DELETE,HEAD,是幂等(Idempotent)的。无论对一个资源操作了多少次,返回的数据均相同。

评论补充

楼主的理解非常的好, 有一些我想补充, 顺别回答其它一些朋友的问题.

根据理查德森模型 (http://martinfowler.com/articles/richardsonMaturityModel.html), REST架构的成熟度有3个等级:
Level 0 POX (这个就不算REST了)
Level 1 Resources
Level 2 Http verbs
Level 3 Hypermedia Controls

楼主所表述的模型在level 2上, 这也是目前大多数RESTful的应用所在的成熟度.

Level 0 POX
这类应用只有一个URI上的上帝接口, 根据交换的XML内容操作所有的资源. 往往导致上帝接口越来越复杂, 越来越难以维护.

Level 1 Resources
这一级别主要解决了上帝接口的问题, 使得各种资源有了自己相应的URI, 虽然仍然是POX的交互方式, 但是每一个接口都更加紧凑和内聚, 相应的容易维护起来.
这里的主要问题是URI templating和URI tunneling.
URI templating带来的结果是服务器端和客户端的紧耦合, 任何时候服务器段想改变自身的URL schema的时候, 都要break已经存在的客户端应用.
URI tunneling带来的问题包含URI templating, 而且放弃了使用http协议标准带来的任何好处, level 2中详述.
早期的rails routes就是url templating/tunneling. Rails3中已经更加靠近level 2了.

Level 2 Http verbs
这一级别使用http verbs来对各种资源进行crud操作, 使得应用程序的接口更加的统一, 语义更加明确. 同时, 因为遵照http的标准进行交互, 很多http提供的好处几乎可以免费的得到.

1. Cache
按照HTTP协议, GET操作是安全的, 幂等(Idempotent)的. 任意多次对同一资源的GET操作, 都不会导致资源的状态变化. 所以GET的结果是可以安全的cache. 所有http提供的cache facilities 都可以被利用起来, 大幅度提高应用程序的性能. 甚至你仅仅只在response里加上cache directives就可以免费获得网络上各级的缓存服务器, 代理服务器, 以及用户客户端的缓存支持. 互联网上几乎所有的应用你都可以粗略统计得到Get VS Non-Get的请求比例约为 4:1. 如果你能为GET操作加上缓存, 那将极大提供你的程序的性能.
2. Robust
在HTTP常用的几个动词里, HEAD, GET, PUT, DELETE 是安全的,幂等的. 因为对同一资源的任意多次请求, 永远代表同一个语义. 所以任何时候客户端发出去这些动词的时候, 如果服务器没有响应, 或者返回错误代码, 客户端都可以非常安全的再次执行同一操作而不用担心重复操作带来不同的语义及最终结果. POST, PATCH操作就不是安全的, 因为当客户端向服务器端发出请求后, 服务器没有响应或者返回错误代码, 客户端是不能安全的重复操作的. 一定只能重新与服务器确认现在的资源状态才能决定下一步的操作.

绝大部分的RESTful应用就停在这里了, 当然也满足绝大多的需求.

Level 3
RESTful的架构本意是”在符合架构原理的前提下,理解和评估以网络为基础的应用软件的架构设计,得到一个功能强、性能好、适宜通信的架构。”
这个世界上规模最大的, 耦合度最低, 最稳定的, 性能最好的分布式网络应用是什么? 就是WEB本身.
规模,稳定,性能都不用说了. 为什么说耦合度低呢? 想一想每个人上网的经历, 你几乎不需要任何培训就可以上一个新的网络购物平台挑选商品,用信用卡付款,邮寄到自己家里.
把网站的程序想像成一个状态机, 用户在一系列状态转换中完成自己的目标. 这中间的每一步, 应用程序都告诉你当前的状态和可能的下一步操作, 最终引导用户从挑选商品,挑选更多商品,到支付页面,到输入信用卡信息,最终完成付费,到达状态机的终点.

这种service discoverablility和self-documenting就是level 3想解决的问题

在这里面, 告诉用户当前状态以及各种下一步操作的东西, 比如链接, 按钮等等, 就是Hypermedia Controls. Hypermedia Controls 就是这个状态机的引擎.

Level 3的REST架构就是希望能够统一这一类的Hypermedia Controls, 赋予他们标准的, 高度可扩展的标准语义及表现形式, 使得甚至无人工干预的机器与机器间的通用交互协议边的可能. 比如你可以告诉一个通用的购物客户端, “给我买个最便宜的xbox”, 客户端自动连上google进行搜索, 自动在前10个购物网站进行搜索, 进行价格排序, 然后自动挑选最便宜的网站, 进行一系列操作最终完成用信用卡付费, 填写个人收件地址然后邮寄.

这些都依赖于Hypermedia Controls带来的这种service discoverablility和self-documenting

更多的关于REST的细节及其应用和实现, 请参考Rest in Practice. 非常非常棒的一本书, 把REST讲的非常透彻.

个人的理解难免有所偏颇, 还请大家批评指正

 

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.