`
mypages
  • 浏览: 89940 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

REST及其在PHP中的现状(包含某些资源抽象方法)

阅读更多

当HTTP被发明出来的时候,其实REST就已经存在了。可惜这么多年来,WEB开发模式却越来越背离HTTP的本质,舍本逐末的追求起RPC之类的东西。此时REST重新回到人们的视线里,无疑让大家开始反思过去走过的弯路。

本文并不想从头介绍REST,只是想举例说明一下需要注意的问题:

先来看看人们对REST的困惑

REST长啥样?

最一般的REST例子,类似下面的样子:

POST   /articles     创建
DELETE /articles/123 删除
PUT    /articles/123 更新或创建
GET    /articles/123 查看


顺便说说几个知识点:

GET操作是安全的。所谓安全是指不管进行多少次操作,资源的状态都不会改变。比如我用GET浏览文章,不管浏览多少次,那篇文章还在那,没有变化。当然,你可能说每浏览一次文章,文章的浏览数就加一,这不也改变了资源的状态么?这并不矛盾,因为这个改变不是GET操作引起的,而是用户自己设定的服务端逻辑造成的。

PUT,DELETE操作是幂等的。所谓幂等是指不管进行多少次操作,结果都一样。比如我用PUT修改一篇文章,然后在做同样的操作,每次操作后的结果并没有不同,DELETE也是一样。顺便说一句,因为GET操作是安全的,所以它自然也是幂等的。

POST操作既不是安全的,也不是幂等的,比如常见的POST重复加载问题:当我们多次发出同样的POST请求后,其结果是创建出了若干的资源。

安全和幂等的意义在于:当操作没有达到预期的目标时,我们可以不停的重试,而不会对资源产生副作用。从这个意义上说,POST操作往往是有害的,但很多时候我们还是不得不使用它。

还有一点需要注意的就是,创建操作可以使用POST,也可以使用PUT,区别在于POST是作用在一个集合资源之上的(/articles),而PUT操作是作用在一个具体资源之上的(/articles/123),再通俗点说,如果URL可以在客户端确定,那么就使用PUT,如果是在服务端确定,那么就使用POST,比如说很多资源使用数据库自增主键作为标识信息,而创建的资源的标识信息到底是什么只能由服务端提供,这个时候就必须使用POST。

浏览器不支持PUT/DELETE方法怎么办?

大部分浏览器只支持GET/POST方法,这使得我们无法完美的实现REST。对于这样的情况,大致有几种解决方法,一种是在表单里加入一个 _method之类名字的隐藏字段,用于表示真正的方法,另一种是使用X-HTTP-METHOD-OVERRIDE头信息来重载POST。

HTTP方法够用么?

从上面的例子,我们可以看到,通过使用已有的HTTP方法:POST,DELETE,PUT,GET就可以完成资源的增删改查,但在实际情况中,我们需要做的操作往往并不仅仅局限在简单的增删改查操作中,比如说我们要把一篇文章“置顶”,但是HTTP方法里没有一个和“置顶”操作相对应的方法,这时候该怎么办呢?REST对类似问题的解决方案是:创建一个新的资源!在上面的例子里,我们可以这样:

PUT /top_articles/123

通过创建出一个新的资源(top_articles),我们就可以使用简单的HTTP方法通吃一切操作了。

如何设计资源的URL?

最常见的资源命名方式是/controllers/id,不过这不是必须的,REST并没有强制规定URL必须符合哪种形式,你大可以按照自己的设想去自由的设计,实际编程时大致有两种方法:

一种是基于路径变量的命名,如:/china/beijing/laowang

基于路径变量的命名方式一般用来描述具有层次化的结构的资源。

另一种是基于查询变量的命名,如:/peopel?name=laowang

基于查询变量的命名方式一般用来描述某种算法的计算结果。

到底是使用基于路径的命名方式,还是基于查询的命名方式,取决于你看问题的角度和个人的喜好。

REST反对使用Session么?


REST拒绝Session!这是因为REST强调无状态性。这里的状态指的的应用状态,也可以称之为会话状态。一旦在服务端保持了这样的状态,那么架构的可扩展性将大打折扣。在REST看来,任何类似的状态本身都应该是一个独立的资源。

但也有人认为,现在可以很方便的把session存储在memcached之类的分布式缓存中,所以不是问题。

Cookie对REST有害么?

一分为二的看,如果Cookie里保存的是应用状态的话,就没有问题。因为应用状态本来就属于客户端。但如果使用Cookie保存类似PHPSESSIONID之类的东西就不对了,因为这样的数据并不属于客户端状态,它只不过是使用Session的借口而已。

再来看看REST在PHP中的现状

PHP里的REST实现案例不多,有点影响都就是CakePHP和Zend,下面分别看看他们的实现:

CakePHP:

设定路由:

Router::parseExtensions('xml');
Router::mapResources('articles');


编写控制器:

class ArticlesController extends AppController {

    var $components = array('RequestHandler');

    function view($id = null) {
        $article = $this->Article->findById($id);
        $this->set(compact('article'));
    }

    // ...
}


视图:

<articles>
<?php echo $xml->serialize($article); ?>
</articles>


差不多就这样了,相应的,还可以实现其他的功能,于是,如下REST操作便成为可能:

POST   /articles
DELETE /articles/123.xml
PUT    /articles/123.xml
GET    /articles/123.xml


总体看,CakePHP的REST实现基本上是按Rails风格来实现的,大体还过得去。

参考链接:

http://book.cakephp.org/view/476/rest
http://c7y.phparch.com/c/entry/1/art,cakephp-rest

ZendFramework:


ZendFramework通过Zend_Rest组件来实现Rest功能:

服务端:

require_once 'Zend/Rest/Server.php';

function sayHello($who, $when)
{
    return "Hello $who, Good $when";
}

$server = new Zend_Rest_Server();
$server->addFunction('sayHello');
$server->handle();


客户端:

require_once 'Zend/Rest/Client.php';

$client = new Zend_Rest_Client('http://path/to/server/script');
$client->
sayHello('Davey', 'Day');
   
echo $client->get();

这时候,我们看一下Web服务器的日志,会发现生成了一条如下的记录:

GET /path/to/servier/script?method=sayHello&arg0=Davey&arg1=Day&rest=1 HTTP/1.1

我们发现,实际操作方法是由URL中的method=sayHello指定的,而HTTP固有方法(GET/POST等)则成为了摆设,这是典型的RPC 风格,如果大家对比Zend_Rest和Zend_XmlRpc文档的话,会明显发现它们根本就是一个东西,所以说,Zend_Rest是一个REST伪实现。

参考链接:

http://framework.zend.com/manual/en/zend.rest.html
http://framework.zend.com/manual/en/zend.xmlrpc.html

=============================

此外,INFOQ上有几篇不错的文章:

http://www.infoq.com/cn/articles/rest-architecure
http://www.infoq.com/cn/articles/rest-introduction
http://www.infoq.com/cn/articles/rest-anti-patterns

http://www.infoq.com/cn/articles/webber-rest-workflow

分享到:
评论

相关推荐

    Drest一个将Doctrine实体暴露为REST资源节点的库

    在描述中提到,Drest 作为一个将 Doctrine 实体暴露为 REST 资源节点的库,意味着它可以将数据库中的记录映射到 REST API 的特定端点。例如,一个 Doctrine 实体“用户”可以通过 REST API 的 `/users` 端点被访问和...

    白话REST-识别真假REST

    REST(Representational State Transfer),即“表征状态转移”,是由Roy Fielding博士在其2000年的博士论文中提出的一种软件架构风格。REST强调基于网络的分布式系统的松耦合设计,并推崇无状态通信机制。在理解...

    Rest WCF资源文件

    - **资源(Resources)**:在REST中,一切皆资源,每个资源都有一个唯一的URI。 - **HTTP方法(HTTP Methods)**:GET用于获取资源,POST用于新建资源,PUT用于更新资源,DELETE用于删除资源。 - **状态码...

    REST与面向资源的Web开发

    REST(Representational State Transfer)代表了一种分布式超媒体软件架构风格,最初由Roy Thomas Fielding在他的2000年博士论文中提出。REST并不是一种具体的标准或者架构,而是一套简单的设计原则和一种架构风格。...

    REST技术研究报告

    REST(Representational State Transfer,表述性状态转移)是一种网络应用程序的设计风格和开发方式,由Roy Thomas Fielding在其博士论文中提出。它强调的是基于HTTP协议的、无状态的、组件化的架构,旨在简化分布式...

    REST实战中文版(有目录)

    首先,REST是基于资源的,意味着系统中的所有内容都被抽象为资源,这些资源通过统一资源标识符(Uniform Resource Identifier,URI)进行访问。每个资源可以拥有多个表示形式(例如JSON或XML格式),客户端和服务器...

    REST实战(REST in Practice)

    - **实际应用**:提供了大量关于如何在日常工作中应用REST的概念和技术的实用指南,使得抽象概念变得更加易于理解。 #### 四、业界评价 - **Mark Nottingham**(雅虎首席技术员):赞扬本书成功地将REST背后通常...

    用WCFWebAPI在MVC3.0下实现REST

    所有的材料上来就是一大堆的名词,SOAP, WSDL,看得头都要大了,后来提出来的REST就容易理解得多,虽然目前SOAP在企业级的web service中还有一席之地,但是在公共的Internet上,不是REST的服务实在不好意思和人打招呼...

    ArcGis Server10 java版Rest服务部署方法

    本文将详细讲解ArcGIS Server 10 Java版的REST服务部署方法,以及如何利用提供的REST.war文件快速进行部署。 首先,理解REST(Representational State Transfer)服务是ArcGIS Server的核心功能之一,它是一种轻量...

    rest for php

    - 类文件:提供基本的REST控制器结构,可能有CRUD操作的抽象方法。 - 示例代码:展示如何使用这个类库创建API。 - 路由配置:如何配置URL以调用不同的API端点。 - 请求和响应处理:处理HTTP请求,返回适当格式的...

    REST实战.pdf 中文完整版

    在Java中实现REST服务,通常会用到JAX-RS(Java API for RESTful Web Services)规范,该规范为构建RESTful服务提供了便利的API。例如,使用`@Path`注解来定义资源路径,`@GET`、`@POST`等注解来指定HTTP方法,以及`...

    Rest 开发API.

    REST的核心概念主要包括资源(Resource)、表示(Representation)、状态转移(State Transfer)以及客户端-服务器模型(Client-Server Model)。 - **资源(Resource)**:网络上的所有事物都可以被抽象成资源,如...

    第四章 Spring MVC Rest风格的url、静态资源标签

    在本章中,我们将深入探讨Spring MVC框架中的RESTful风格URL设计以及如何处理静态资源。REST(Representational State Transfer)是一种软件架构风格,常用于Web服务设计,它强调通过HTTP方法(如GET、POST、PUT、...

    REST与SOA两种架构

    标题中的“REST与SOA两种架构”涉及到的是两种不同的服务架构设计模式,它们在软件工程领域,特别是分布式系统设计中占据着重要的地位。REST(Representational State Transfer,表述性状态转移)和SOA(Service-...

    REST in practice,英文

    3. **资源模型**:书中可能会讨论如何设计资源及其关系,以及如何通过URI有效管理这些资源。 4. **状态管理和超媒体**:REST强调无状态,这意味着每个请求都应包含所有必要的信息,而服务器不需要保持客户端的上...

    rest开发小总结

    REST的核心概念包括资源(Resource)、URI(Uniform Resource Identifier)和表现层(Representation)。在RESTful API设计中,每个资源都有一个唯一的URI,通过HTTP方法(GET、POST、PUT、DELETE等)来操作资源。 ...

    Rest架构概述

    1. 无状态性:在REST架构中,每个请求都包含执行操作所需的所有信息,无需保存会话状态。这大大降低了服务器的负担,提高了系统的可伸缩性,同时也提高了系统的可靠性和效率。 2. 统一接口:REST要求所有服务器必须...

    REST WebService简单应用

    在"REST WebService简单应用"这个主题中,可能涉及的知识点包括如何创建一个简单的RESTful服务,使用JAX-RS(Java API for RESTful Web Services)框架,这是一个Java平台上的REST实现。JAX-RS提供了一种声明式的...

Global site tag (gtag.js) - Google Analytics