最近依舊在忙公司 KM 的項目,我負責的是部分核心模塊的開發,已經實現了Servcie - DAO 層的開發,緊接開始着手實現 Controller 層,由於是基於 RESTful,因此必須定義好 RESTful API 的接口,才能進行功能的實現。學習
由於對 RESTful 理解的比較少,因此參考了GitHub的設計開發原則,如下的內容是我根據對 RESTful 的理解,針對公司項目設計接口。設計
Disk : 網盤code
網盤列表對象
Folder : 目錄 (即網盤下的文件夾)排序
目錄列表接口
目錄重命名ci
目錄移動資源
目錄批量移動開發
目錄下載文檔
目錄批量下載
File :文件(只能存在於目錄下,不能存在網盤下)
文件列表(展現該目錄下的子目錄和文件)
文件收藏
文件分享
文件批量下載
RESTful 的關鍵
RESTful 定義可表示流程元素/資源的對象。在 REST 中,每個對象都是經過URL來表示的,對象用戶負責將狀態信息打包進每一條消息內,以便對象的處理老是無狀態的
資源分爲單個文檔和集合,儘可能使用複數來表示資源,單個資源經過添加 id 或者 name 等來表示
一個資源能夠有多個不一樣的 URL
資源能夠嵌套,經過相似目錄路徑的方式來表示,以體現它們之間的關係
注意:根據RFC3986定義,URL是大小寫敏感的。因此爲了不歧義,儘可能使用小寫字母
Method
舉例:GitHub上對倉庫的增刪查改
GET /repos/:owner/:repo/issues GET /repos/:owner/:repo/issues/:number POST /repos/:owner/:repo/issues PATCH /repos/:owner/:repo/issues/:number DELETE /repos/:owner/:repo
Method | 描述 |
---|---|
GET | 獲取資源 |
POST | 建立資源,會返回建立的資源 |
PATCH | 更新資源的部分屬性。由於 PATCH 比較新,並且規範比較複雜,因此真正實現的比較少,通常都是用 POST 替代,會返回更新的資源 |
PUT | 替換資源,客戶端須要提供新建資源的全部屬性。若是新內容爲空,要設置 Content-Length 爲 0,以區別錯誤信息,會返回更新的資源 |
DELETE | 刪除資源 |
把動做轉換爲資源
在設計的過程當中,會發現,除了 CRUD 這四種操做,咱們還會遇到其餘的操做,這樣就給咱們在 API 的設計帶來很大的麻煩,然而,RESTful 是一種設計風格而不是標準,只是提供了一組設計原則和約束條件,因此咱們能夠對接口進行靈活的設計,從而知足咱們的業務需求。最常規的作法是爲須要的動做增長一個 endpoint,選擇一個 Method 來執行動做,好比 POST /email/:emailId/resend 從新發送郵件
舉例:GitHub上對倉庫的加星操做
PUT /gists/:id/star DELETE /gists/:id/star
Query 實現更自由的查詢
在對接口進行操做的時候,除了一些必要的參數,有時候須要一些非必要的參數進行條件控制,是用 query 參數進行控制,避免了在接口設計的硬性規定,實現更大的自由度。
舉例: 查詢某個 repo 下面 issues 的時候,能夠經過如下參數來控制返回哪些結果:
state:issue 的狀態,能夠是 open,closed,all
since:在指定時間點以後更新過的纔會返回
assignee:被 assign 給某個 user 的 issues
sort:選擇排序的值,能夠是 created、updated、comments
direction:排序的方向,升序(asc)仍是降序(desc)
per_page:每頁返回多少資源,若是沒提供會使用預設的默認值
page:要獲取哪一頁的資源,默認是第一頁
批量操做實現
設計方法有不少種,借用Backbone.js 的說法:There's More Than One Way To Do It,不要太糾結
舉例:多種設計方案
//簡約的設計 GET /ec2/instance/batch?id=aa,bb,cc: //健壯的設計 GET /ec2/instance?batch={"ids":["aa","bb","cc"]}: // GET /ec2/instance?batch=[{"method":"DELETE","id":"aa"},{"method":"DELETE","id":"bb"},{"method":"DELETE","id":"cc"}]:
Disk : 網盤
網盤列表 :/disks
Folder : 目錄 (即網盤下的文件夾)
目錄列表 :GET: /disks/:diskId/folders
目錄重命名 :PATCH:/disks/:diskId/folders/:folderId/rename/:name
目錄移動 :PATCH:disks/:diskId/folders/:folderId/moveto/folderId/:folderId
目錄下載 :GET:disks/:diskId/folders/:foderId/download
File :文件(只能存在於目錄下,不能存在網盤下)
文件列表 :GET:disks/:diskId/folders/:folders/files
文件收藏 :PATCH:disks/:diskId/folders/:folderId/files/:fileId/collect
文件分享 :PATCH:disks/:diskId/folders/:folderId/files/:fileId/share
批量操做:
多個fileObj移動:PATCH:disks/:diskId/fileobjs/moveto/folderId/:folderId?請求包體
多個fileObj刪除:DELETE:disks/:diskId/fileobjs?請求包體
多個fileObj下載:GET:disks/:diskId/fileobjs/download?請求包體
請求包體:
請求包體:"fileObjects": [ { "fileObjectId": fileId, "isFolder": true / false } ]
以上的設計其實還沒獲得上級的經過,其實還須要繼續改進,不過這一輪的設計讓我對 RESTful 的使用有了必定的瞭解,雖然還沒深刻研究 RESTful 核心的部分,可是,經過 URL 操做資源這種設計思路,的確是讓人眼前一亮。