restful的實例論證
時下經常流行這各種概念型術語,一時間真的讓很多人難以抓摸頭腦。本文為大家講解一下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路由器分析加載方式,如下圖:
從上圖可以清晰了解到PESCMS的一個完整流程。用戶的每一個請求,均是基于提交的URL進行處理。只要URL中能夠分析出對應的組,模型,方法程序就可以正常運作。
放眼觀望,此設計流程非常符合PHP的開發模式,我當時也是這樣認為的。不過最近因為在研究網站的安全性,在抓包過程中,忽然頓悟到此模式存在一個缺點:耦合性很高。
以PESCMS的程序運作來說:當用戶訪問PESCMS時,程序路由器根據用戶提交的URL找到控制器,并實體化后。接著首要的第一件事必然會是,父類公共函數的構造函數被觸發,執行一系列的動作。諸如:判斷網站是否關閉,用戶是否登錄與用戶信息,獲取導航菜單,面包屑,列表內容等等。到最后才到控制器的方法執行。
若當前用戶為查看內容,上述的動作一點都不耦合。可用戶要執行僅為登陸操作呢?該系列動作反而變得多余了。并且在大數據的今天,能夠節省一個動作所帶來的速度提升是不可言喻的。
接下來,根據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></pre>
模板引擎解析模板,會自動插入對應的隱藏域,的確變得簡單了。:)
注: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