REST 首先只是一种架构样式,不是一种标准。这点和 Ajax 类似,两者都是利用现有的成熟技术。在 REST 的定义中,一个 Web 应用总是使用固定的 URI 向外部世界呈现(或者说暴露)一个资源。

注:URI 是英文 Uniform Resource Identifier 的缩写,中文翻译“通用资源标志符”。“通用资源标志符”是指唯一标识一个资源(xhtml 文件、图片、css 样式表)的字符串。当然了,RFC 中定义的 URI 复杂得多,不过我们此处将 URI 想象成一个人的身份证号码就行了(你不能有两个同时有效的身份证号码,一个号码也不可能同时对应两个人)。而我们天天挂在嘴边的 URL 地址就是 URI 的一种表现形式(个人理解,有错请纠正)。

知道什么是URI 后,我们来看一个实际例子:

http://www.example.com/photo/logo 指向 example.com 网站(可以视为一个 Web 应用)中类型为 photo,名字为 logo 的资源。我们用浏览器访问这个URI,看到的将可能是一个 xhtml 文档,其中用<img src=”……” />来显示实际的照片。

http://www.example.com/photo/logo 很容易让你想到 URL 重写。事实上,这个地址很可能会在服务器内部处理为 http://www.example.com/photo.php?name=logo 这样的地址。photo.php 是服务器端的一个动态脚本文件,根据 name 参数生成 xhtml 文档返回给浏览器。

现在假设我们要获取这张照片的 XML 文档。XML 文档中包含照片的文件名、文件大小、拍摄日期等等信息。也就是说我们要获取“同一个资源的不同表现形式的数据”。对于这个要求,我们可以很容易的用另一个 URL 地址达到:http://www.example.com/xml/logo。

但是,这就违背了“URI 唯一标识一个资源”的定义。如果我们要获取同一个资源的多种表现形式,那么就要使用更多的 URL,从而给一个资源指定了多个不同的 URI。

而在 REST 中,不管是获取照片的 xhtml 文档还是 XML 文档,或者照片文件本身,都是用同一个 URI,就是 http://www.example.com/photo/logo。

那这是怎么办到的呢?Ruby On Rails 中是通过分辨 HTTP Request Header 信息来分辨客户端是想要取得资源的哪一种表现形式的数据。

当我们用浏览器访问一个网址时,浏览器会构造一个 HTTP 请求。这个请求有一个头信息,其中包括了本次请求接受何种类型的数据。通常浏览器发送的 HTTP 请求头中,Accept 的值都是 */*,也就说接受服务器返回的任何类型的数据。

看到这里,聪明的家伙应该知道了。只要我们指定一个特定的 Accept 参数,那么服务器就可以通过判断该参数来决定返回什么类型的数据。所以在一个采用 REST 架构的应用中,要获取同一个资源的不同表现形式的数据,只需要使用不同的 HTTP 请求头信息就行了。

如果考虑为 Web 应用增加 Web Services,这种技术的价值就体现出来了。比如我写了一个 Delphi 程序,现在只需要构造一个包含 Accept: text/xml 的 HTTP 请求头,然后将请求发送到 http://www.example.com/photo/logo 就可以了。返回的结果就是一个 XML 文档,而不是 xhtml 文档。

因为我们的 HTTP 请求头信息有不同的状态,从而可以获得不同的数据,所以叫做“具象状态传输” :)

除了上面的用法,REST 还有进一步的扩展。

我们在 Web 应用中处理来自客户端的请求时,通常只考虑 GET 和 POST 这两种 HTTP 请求方法。实际上,HTTP 还有 HEAD、PUT、DELETE 等请求方法。而在 REST 架构中,用不同的 HTTP 请求方法来处理对资源的 CRUD(创建、读取、更新和删除)操作:
◆POST: 创建 
◆GET: 读取 
◆PUT: 更新 
◆DELETE: 删除

经过这样的一番扩展,我们对一个资源的 CRUD 操作就可以通过同一个 URI 完成了:
http://www.example.com/photo/logo(读取)
仍然保持为 [GET] http://www.example.com/photo/logo

http://www.example.com/photo/logo/create(创建)
改为 [POST] http://www.example.com/photo/logo

http://www.example.com/photo/logo/update(更新)
改为 [PUT] http://www.example.com/photo/logo

http://www.example.com/photo/logo/delete(删除)
改为 [DELETE] http://www.example.com/photo/logo

从而进一步规范了资源标识的使用。

通过 REST 架构,Web 应用程序可以用一致的接口(URI)暴露资源给外部世界,并提供对资源的操作服务。这对于以资源为中心的 Web 应用来说非常重要。例如照片共享网站、用户社区等。

Ruby On Rails 1.2 版对 REST 有很好的支持,但要在 PHP 中应用 REST 还需要解决不少问题:

◆如何在服务端判断 PUT、DELETE 请求方法; 
◆如何获取用 PUT、DELETE 请求方法中传递的数据; 
◆如何获取 HTTP 请求头信息中的 Accept 参数值; 
◆如何在浏览器端发起 PUT 和 DELETE 请求。

不过我仔细看了PHP文档,我觉得上面几个问题都是可以解决的。

服务端综合使用$_SERVER['HTTP_ACCEPT']、$_SERVER['REQUEST_URI']、$_SERVER['REQUEST_METHOD']、$_SERVER['QUERY_STRING'] 这些变量应该可以搞定前面三个问题。而第四个问题则可以用 JavaScript 的XMLHttpRequest 对象来实现。

不过我想 REST 的真正价值在于 Web Services,而不是通过浏览器操作的应用程序。

【编辑推荐】

    1. 轻量级REST框架Restlet 1.1.0发布

热门Web开发方式 REST实现原理浅析的更多相关文章

  1. Dubbo学习(一) Dubbo原理浅析

    一.初入Dubbo Dubbo学习文档: http://dubbo.incubator.apache.org/books/dubbo-user-book/ http://dubbo.incubator ...

  2. vue的双向绑定原理浅析与简单实现

    很久之前看过vue的一些原理,对其中的双向绑定原理也有一定程度上的了解,只是最近才在项目上使用vue,这才决定好好了解下vue的实现原理,因此这里对vue的双向绑定原理进行浅析,并做一个简单的实现. ...

  3. Web服务器的工作原理

    Web服务器的工作原理 Web服务器工作原理概述 很多时候我们都想知道,web容器或web服务器(比如Tomcat或者jboss)是怎样工作的?它们是怎样处理来自全世界的http请求的?它们在幕后做了 ...

  4. Web程序的运行原理及流程(一)

    自己做Web程序的开发也有两年多了 从最开始跟风学框架  到第一用上框架的欣喜若狂 我相信每个程序员都是这样过来的 在大学学习一门语言 学会后往往很想做一个实际的项目出来  我当时第一次做WEB项目看 ...

  5. HTTP长连接和短连接原理浅析

    原文出自:HTTP长连接和短连接原理浅析

  6. Javascript自执行匿名函数(function() { })()的原理浅析

    匿名函数就是没有函数名的函数.这篇文章主要介绍了Javascript自执行匿名函数(function() { })()的原理浅析的相关资料,需要的朋友可以参考下 函数是JavaScript中最灵活的一 ...

  7. Python Web框架 tornado 异步原理

    Python Web框架 tornado 异步原理 参考:http://www.jb51.net/article/64747.htm 待整理

  8. [转帖]Git数据存储的原理浅析

    Git数据存储的原理浅析 https://segmentfault.com/a/1190000016320008   写作背景 进来在闲暇的时间里在看一些关系P2P网络的拓扑发现的内容,重点关注了Ma ...

  9. Android-Binder原理浅析

    Android-Binder原理浅析 学习自 <Android开发艺术探索> 写在前头 在上一章,我们简单的了解了一下Binder并且通过 AIDL完成了一个IPC的DEMO.你可能会好奇 ...

随机推荐

  1. MongoDB (四) MongoDB 数据模型

    在 MongoDB 中的数据有灵活的模式.在相同集合中文档并不需要有相同的一组字段或结构的公共字段的集合,文档可容纳不同类型的数据. MongoDB设计模式的一些考虑 可根据用户要求设计架构. 合并对 ...

  2. QT+VS编译器处理字符串时的坑真是多

    以下因素都有影响:1. QT4与QT5对字符串编码的处理不同(最好不要在源代码里直接写中文,坑更多)2. QTextCodec自动对编码转换的影响3. 源代码文件对编码存储格式的不同会影响编译器对字符 ...

  3. 嵌入式linux的学习之路[转]

    我认为的一条学习嵌入式Linux的路: 1)学习 Linux系统安装. 常用命令.应用程序安装. 2) 学习 Linux 下的 C 编程.这本书必学<UNIX 环境高级编程>.<UN ...

  4. Linux和远程系统同步文件(未完成)

    实验环境: 本地主机:192.168.0.1 远程主机:192.168.0.101 1. 使用 scp,把/root/tardir1/achieve2.tar.gz复制到远程主机的root用户的hom ...

  5. Model元数据解析

    Model 元数据是针对数据类型的一种描述信息,主要用于控制数据类型本身及其成员属性在界面上的呈现方式,同时也为Model 绑定和验证提供必不可少的元数据信息.一个复杂数据类型通过属性的方式定义了一系 ...

  6. ruby脚本,随机生成复杂密码

    简单版本: base_char = (32..126).map{|i|i.chr} - ["'",'"'," ", "`",&qu ...

  7. weblogic11g 节点管理器 nodemanager

    Weblogic 节点管理器  nodemanager 一.Weblogic  规划 : Server名称 端口 ip 备注 xyyadmin 7001 10.10.54.74 管理server ap ...

  8. spring各个包之间的依赖关系

    从图中可以看到: 1.spring core,spring beans被其他较多包依赖,spring aop,spring context,spring expression分别被两个包依赖,而spr ...

  9. ORACLE EBS R12 - 寄售功能知多少

    材料以寄售方式供应,是制造业实现零库存管理的一种方式.东西放在我这里,不用的时候,东西还是供应商的,用的时候,按"装机"数量进行付款.这种业务模式,对于竞争日趋白热化的家电行业,非 ...

  10. [CF189A]Cut Ribbon(完全背包,DP)

    题目链接:http://codeforces.com/problemset/problem/189/A 题意:给你长为n的绳子,每次只允许切a,b,c三种长度的段,问最多能切多少段.注意每一段都得是a ...