restful的实例论证

jopen 10年前

    时下经常流行这各种概念型术语,一时间真的让很多人难以抓摸头脑。本文为大家讲解一下restful,以我的个人观点,带上实际例子来举证restful的优缺点和实现方法。

  • 什么是restful?

    restful相信大家或多或少有听说/使用过。如果您还不直到restful是啥玩意,可以点击维基的说明进行知识增进。

    从维基的说明中,可以明确知道restful具有四种状态请求:GET,POST,PUT,DELETE。四种请求中,仅有GET,POST可以直接用form表单进行提交请求。PUT和DELETE只有在部分浏览器下可以获得支持(据我实测发现,通过JQ的$.ajax方法中,type可以设置对应的请求方式)。

    可惜的时,即使浏览器支持,但开发语言未必能够支持。如PHP并没有提供$_PUT,$_DELETE 的接收方式。当然,这并不是说PHP不支持,后文我将讲述实现restful几种方法。

  • restful的优缺点

    要知道restful的优缺点,必然先知道用到restful和没有用到restful的区别。下面我将以我写的PESCMS程序实例说明。

    PESCMS开发初期,我也考虑过要不要用restful。当时苦搜资料,网上提及到的也仅仅是概念。于是根据我个人的看法,抛弃了繁琐的restful设计,选用传统URL路由器分析加载方式,如下图:

restful的实例论证

    从上图可以清晰了解到PESCMS的一个完整流程。用户的每一个请求,均是基于提交的URL进行处理。只要URL中能够分析出对应的组,模型,方法程序就可以正常运作。

    放眼观望,此设计流程非常符合PHP的开发模式,我当时也是这样认为的。不过最近因为在研究网站的安全性,在抓包过程中,忽然顿悟到此模式存在一个缺点:耦合性很高。

    以PESCMS的程序运作来说:当用户访问PESCMS时,程序路由器根据用户提交的URL找到控制器,并实体化后。接着首要的第一件事必然会是,父类公共函数的构造函数被触发,执行一系列的动作。诸如:判断网站是否关闭,用户是否登录与用户信息,获取导航菜单,面包屑,列表内容等等。到最后才到控制器的方法执行。

    若当前用户为查看内容,上述的动作一点都不耦合。可用户要执行仅为登陆操作呢?该系列动作反而变得多余了。并且在大数据的今天,能够节省一个动作所带来的速度提升是不可言喻的。

    接下来,根据restful的特点,我重构了一下网站的实现流程。流程图如下:

restful的实例论证

    根据调整,现在用户的每一个动作,均是基于G,P,P,D状态进行,继而执行对应的控制器。调整后,视图的输出不在为全局所共有(实际上不一定这样,因为这仅为一个设计要求),仅属GET请求。剩下的请求,输出的为状态视图或者不输出。

    什么是状态视图?可以理解为操作结果的提示动作。如:用户执行创建/更新/删除等动作后,程序是否有必要显示他的执行结果。相对于js中ajax的回调结果。因此,可有可无。

  • restful的实现方法

    上面说了一大段理论,相信大家还是有会点摸不着头脑。下面我来用更加真是的PHP代码来说明如何实现restful。如果您有学习过laravel框架,那么可以直接跳开这里。

    先来说明一下laravel框架的实现方法(实际上我没有用过laravel,仅为网上搜索,错误望指正):laravel框架要实现G,P,P,D。需要在表单中嵌入一个隐藏的表单。

<input type="hidden" name="_method" value="PUT">

     声明此处为PUT。接着路由器会依据此隐藏表单进行判断您所提交的方法请求,剩下的方法也如此操作。我参考的原文地址:http://stackoverflow.com/questions/14756994/how-does-laravel-handle-put-requests-from-browsers

    上述的方法我觉得不太优雅,而且每次都得在手动在表单中插入隐藏域声明请求类型。当然,我下班路程时,我想到使用模板引擎来实现,将变得非常便捷。如下代码:

@{form action="" method="post" http="put"}  @{/form}  #说明,模板解析后会是:  <form action ="" method="post">  <input type="hidden" name="_method" value="PUT">  </form>

    模板引擎解析模板,会自动插入对应的隐藏域,的确变得简单了。:)

    注:PUT和DELETE提交方式不一定为POST形式提交,视您提交数据是否要明确POST。

    当然了,作为一名反模板引擎的支持者。在不支持模板引擎的程序中,要如何实现呢?可以通过URL分析请求行为。具体表现为:

    GET操作: www.oschina.net/post/1 读取文章 www.oschina.net/post/edit/1 编辑文章

    POST操作(表单提交):www.oschina.net/post 添加文章

    PUT操作(GET方式链接): www.oschina.net/put/post/1  更新文章

    DELETE操作:www.oschina.net/delete/post/1 删除文章

    由于PUT和DELETE都是基于GET的形式提交,因此路由器必须优先拆解URL,确保pathinof首要参数是否存在上述两个请求。

    除了上述两种方法,如果你是不考虑程序的浏览器兼容性,可以使用全局ajax来进行实现。经过我的实测,在JQ的$.ajax中,type类型可以任意填写。并且在$_SERVER['REQUEST_METHOD']返回的一致。还有使用CURL等形式实现,这里我就不一一列举了。

  • restful总结

    restful本身没有正式标准,因此一千个人有一千种实现方式。我个人的理解是:restful的提出,仅仅是出于对资源请求细分和规范,以便程序的开发与对接更加清晰合理。我们不必因为restful带来的优势,就急切将程序全线切换到restful设计中去。因为使用restful,虽然节省了程序的资源请求浪费,降低程序的耦合性。但在这种细分的颗粒度下,如何保持程序的复用性与结构的稳健,是每一位restful使用者今后的必修课。

 

 来自:http://my.oschina.net/Felldeadbird/blog/304926