# 第2節 以豆瓣網為例, 講解restful api設計規范
* **什么是restful api**
* 目前比較成熟的一套互聯網應用程序的API設計理論豆瓣電影api
## [豆瓣電影api](https://developers.douban.com/wiki/?title=movie_v2)
1. 應該盡量將API部署在專用域名之下
http://api.douban.com/v2/user/1000001?apikey=XXX
2. 應該將API的版本號放入URL
http://api.douban.com/v2/user/1000001?apikey=XXX
3. 在RESTful架構中,每個網址代表一種資源(resource),所以網址中不能有動詞,只能有名詞,而且所用的名詞往往與數據庫的表格名對應。一般來說,數據庫中的表都是同種記錄的"集合"(collection),所以API中的名詞也應該使用復數。
http://api.douban.com/v2/book/:id (獲取圖書信息)
http://api.douban.com/v2/movie/subject/:id (電影條目信息)
http://api.douban.com/v2/music/:id (獲取音樂信息)
http://api.douban.com/v2/event/:id (獲取同城活動)
4. 對于資源的具體操作類型,由HTTP動詞表示。常用的HTTP動詞有下面四個(對應增/刪/改/查)。
GET(select):從服務器取出資源(一項或多項)。
eg. 獲取圖書信息 GET http://api.douban.com/v2/book/:id
POST(create):在服務器新建一個資源。
eg. 用戶收藏某本圖書 POST http://api.douban.com/v2/book/:id/collection
PUT(update):在服務器更新資源(客戶端提供改變后的完整資源)。
eg. 用戶修改對某本圖書的收藏 PUT http://api.douban.com/v2/book/:id/collection
DELETE(delete):從服務器刪除資源。
eg. 用戶刪除某篇筆記 DELETE http://api.douban.com/v2/book/annotation/:id
5. 如果記錄數量很多,服務器不可能都將它們返回給用戶。API應該提供參數,過濾返回結果
?limit=10:指定返回記錄的數量
eg. 獲取圖書信息 GET http://api.douban.com/v2/book/:id?limit=10
6. 服務器向用戶返回的狀態碼和提示信息
每個狀態碼代表不同意思, 就像代號一樣
2系 代表正常返回
4系 代表數據異常
5系 代表服務器異常
| 錯誤碼 | 錯誤信息 | 含義 | 狀態碼 |
| --- | --- | --- | --- |
| 6000 | book_not_found | 圖書不存在 | 404 |
| `6002` | `unauthorized_error` | 沒有修改權限 | 403 |
| 6004 | review_content_short(should more than 150) | 書評內容過短(需多于150字) | 400 |
| 6006 | review_not_found | 書評不存在 | 404 |
| 6007 | not_book_request | 不是豆瓣讀書相關請求 | 403 |
| 6008 | people_not_found | 用戶不存在 | 404 |
| 6009 | function_error | 服務器調用異常 | 400 |
| 6010 | comment_too_long(should less than 350) | 短評字數過長(需少于350字) | 400 |
| 6011 | collection_exist(try PUT if you want to update) | 該圖書已被收藏(如需更新請用PUT方法而不是POST) | 409 |
| 6012 | invalid_page_number(should be digit less than 1000000) | 非法頁碼(頁碼需要是小于1000000的數字) | 400 |
| 6013 | chapter_too_long(should less than 100) | 章節名過長(需小于100字) | 400 |
## 接口安全
1. API的身份認證應該使用OAuth 2.0框架。
2. 技術團隊自己約定的規則
?增加兩個參數 `time`, `token`?
? ?`token`為時間戳加密后的字符串, 加密規則只有你們技術團隊自己知道
? ?time為時間戳, 用于判斷接口請求是否超時