RESTful API,是一種 API 設計風格並不是種標準,是由 Roy Fielding 在 2000 年所提出,同時他也是 HTTP 規範的主要作者之一。
一般 API 我們會這樣定義 動詞+名詞
舉了例子假設我們要取得 User 相關的 api 會這樣設計
[GET] https://url.com/getUser?user_id=1 # 取得會員資料
[POST] https://url.com/newUser # 建立會員資料
[POST] https://url.com/editUser # 修改會員資料
[DELETE] https://url.com/deleteUser?user_id=1 # 刪除會員資料
這樣設計的問題是把 API 每個動作都切開成不一樣的路徑,但是都是在處理 User 相關的 API,在使用上我們就要去記住修改會員資料是用 editUser
而不是 modifyUser
,也就造成了命名上的問題,如果事先沒溝通好那就悲劇啦。
這邊也分享一個之前看過的一個 API 名詞/動詞
的設計方式 注:非當事API
[GET] https://url.com/user/get/?user_id=1 # 取得會員資料
[POST] https://url.com/user/create/ # 建立會員資料
[POST] https://url.com/user/edit/ # 修改會員資料
[DELETE] https://url.com/user/delect/?user_id=1 # 刪除會員資料
這樣好像也很好的解決我上面說的需要溝通的問題,但是我們可以驚覺這樣我們沒好好善用 Http Request Method 的特性啦,此時 RESTful API 就提供了一套設計方法。
注:Http Request Method 意指提出 Request 同時可以指定要哪一種方法,常見的有 GET, POST, PUT, DELETE。
那麼採用 RESTful API 來設計的話就不一樣啦!會變成這樣
[GET] https://url.com/user/1 # 取得會員資料
[POST] https://url.com/user/ # 建立會員資料
[PUT] https://url.com/user/1 # 修改會員資料
[DELETE] https://url.com/user/1 # 刪除會員資料
注:上述 1 為 user_id
RESTful API 的設計方法呢,是把 user 視為一種 resource 而我們對這個 resource 去做 CRUD,我們就可以很簡單口語化這樣去解釋,建立會員資料用 POST
取得會員資料用 GET
修改資料用 PUT
刪除會員資料 DELETE
而 resource name 則都是 user
因此使用上就有一個規則可循這便是 RESTful API 最大的優點。
注:CRUD 意指 CREATE(新增),READ(讀取),UPDATE(更新),DELECT(刪除)。
當然有人會說 /newUser
還是 user/create
也很口語化啊也讓人一看就懂啊,那前面也說了 RESTfull API 呢是一種設計方法而非準則或是定理,當然使用上也是要適當的變化。
承接上述 user 例子如果要加入 login 的功能的話好像就無法使用了吧,這時我們可以這樣變化去設計。
[PUT] https://url.com/user/login # 註冊帳號
[POST] https://url.com/user/login # 登入取得 token
[DELETE] https://url.com/user/login # 註銷登入 token
[GET] https://url.com/user/1 # 取得會員資料
[POST] https://url.com/user/ # 建立會員資料
[PUT] https://url.com/user/1 # 修改會員資料
[DELETE] https://url.com/user/1 # 刪除會員資料
直接在 user 這個 resource 下新增一個 login 的 resource 這樣就可以啦。
這樣設計 API 仍然不太 make sense 顯而易見的就有一個問題,user 這組 api 可以傳送 user_id 來看到其他人的資料也能修改,為了解決這個問題我們可以利用 head 包 Authorization 將登入取得的 token 傳入增加安全性
就可以避免看到不該看到的資料,另外由於 user 這組 api 可能之後會有好友功能因此將個人資料部分獨立於 user/profile
,也順道設計 user/friends
的相關 api。
注:token 通常是指我們在登入後跟後台取得的一組唯一值,而把 token 傳進 api 後端的程式就會知道這組 token 對應到哪一個 user,而每次登入取得的 token 都會不同,因此我們就可以讓 api 知道說誰重複登入了也可以做到 token 過期這件事情。
[PUT] https://url.com/auth/ # 註冊帳號
[POST] https://url.com/auth/ # 登入取得 token
[DELETE] https://url.com/auth/ # 註銷登入 token
[GET] https://url.com/user/profile # 取得會員資料,需要 token
[POST] https://url.com/user/profile # 建立會員資料,需要 token
[PUT] https://url.com/user/profile # 修改會員資料,需要 token
[DELETE] https://url.com/user/profile # 刪除會員資料,需要 token
[GET] https://url.com/user/friends # 取得好友名單,需要 token
[POST] https://url.com/user/friends/2 # 新增好友,需要 token
[PUT] https://url.com/user/friends/2 # 修改好友,需要 token
[DELETE] https://url.com/user/friends/2 # 刪除好友,需要 token
注:上述 2 為好友的 friend_id
那如果我們又想要有 group 的功能也能依樣畫葫蘆。
[GET] https://url.com/group/3 # 取得 group 資料,需要 token
[POST] https://url.com/group/ # 新增 group 資料,需要 token
[PUT] https://url.com/group/3 # 修改 group 資料,需要 token
[DELETE] https://url.com/group/3 # 刪除 group 資料,需要 token
[POST] https://url.com/group/3/user/ # 加入指定的 group,需要 token
[DELETE] https://url.com/group/3/user/ # 離開指定的 group,需要 token
注:上述 3 為好友的 group_id
在個 group 的例子呢,設計上因為我希望 group 是跟 user 是不同的 resource 因此不是 user/group
而是直接使用 group
這樣的設計,加入或離開 group 呢使用前面所說的在 head 中包 Authorization 塞 token 的方法一樣這樣就知道誰要加入離開群組啦。
看到這裡也許你有不同想法,RESTfull API 也只是個設方法而已使用上還是要看系統整體的架構設計,那這篇文章就到這裡感謝各位收看。