經常聽到rest風格api這個詞,那麼到底什麼是rest api呢?(Representational State Transfer)?表述性狀態轉移?《Spring實戰》上說:REST就是將資源的狀態已最合適的形式從服務器端轉移到客戶端。我在看了很多博客和資料後仍然感覺到頭大,我個人感覺關於這方面的資料很混亂,當然我確實也沒有那個心思去看REST提出者Roy Fielding的那篇博士論文Architectural
Styles and the Design of Network-based Software Architecture
很多資料上比較混亂的地方和我比較疑惑的地方是,比如:(1)協議到底要不要帶版本號呢?帶的話,標準做法是放到url中還是放到header中呢?對此,很多文章各持己見。(2)很多人自稱自己的做法是rest的,但是很多接口不區分增刪改查都用的是post方法,或者只用get(用於查詢資源),和post(用於增加、刪除和修改) (3)按照“標準”,查詢資源應該是get方法,可是有時候有些接口很複雜,查詢參數可能有幾十甚至上百個那麼多,很有可能會超過get請求的url長度最大限制啊。所以,我一度懷疑rest api是否真的適用於複雜接口的設計。(4)接口的url設計到底怎樣是“標準”的。比如,查詢作者名爲tom的、分類爲文學的書籍,http://域名/books/author/tom/class/literature
還是 http://域名/books?author=tom&class=literature ,這兩種那種是標準的呢?或者這兩種都可以?
或者,我感覺實在是沒必要鑽牛角尖。那麼,我就談談我對rest api的幾點粗淺的認識吧:
(1)rest api操作的是資源,一個url就是一個資源,url中不應該出現動詞
(2)rest api對資源的操作包括C(Create) R(Read) U(Update) D(Delete),即增、查、改、刪,分別對應的http方法是 post、get、put 、delete。不同的接口可能對應的是同一個url,這時候不同的http方法就構成了不同的操作了。
(3)rest api是無狀態的,請求之間不應該有依賴。回想常見的網站架構,用戶登錄後將相關信息存放到session中,該用戶以後的相關操作從session中驗證權限。在rest中,要放棄session的使用,每一個請求之間是獨立的,每個需要鑑權的接口都要帶上鑑權信息。這種無狀態性有利於服務器的擴展。
下面,我簡單介紹下我最近寫的一個demo。
(1)項目簡介
這個demo很簡單,是一個記賬小工程。用戶可以註冊、修改密碼,可以記賬、查找記賬記錄等。
(2)接口介紹
用戶操作相關:
post /users 用戶註冊
post /users/login 用戶登錄(這裏我把login當成一個名詞)
put /users/pwd?userId=xxx&sign=xxx 用戶修改密碼
delete /users?uerId=xxx&sign=xxx 刪除用戶
記賬記錄操作相關:
post /records?userId=xxx&sign=xxx 增加一條記賬記錄
get /records/:id?userId=xxx&sign=xxx 查詢一條記賬記錄詳情
put /records/:id?userId=xxx&sign=xxx 修改一條記賬記錄詳情
get /records?查詢參數&userId=xxx&sign=xxx 分頁查詢記賬記錄
delete /records/:id?userId=xxx&sign=xxx 刪除一條記賬記錄
(3)關於redis和數據庫的說明
服務端在用戶登錄後,生成token,並將token保存到redis中。後面在接口鑑權的時候會取出token計算簽名,進行比對。
這個demo搭建了一個redis主從複製,具體可以參考:http://download.csdn.net/detail/zhutulang/9585010
數據庫使用mysql,腳本在 src/main/resources/accounting.sql
(4)項目地址
關於demo的細節這裏就不在詳述了,這個工程以後會再優化。demo可以在這裏下載:http://download.csdn.net/detail/zhutulang/9586998