學習Restful API設計

關於API設計

       最近工作寫API的需求越來越頻繁,如何設計API的風格,是需要花心思和一些時間
就特定寫了一篇關於API設計原則

1.HTTPS
 
     雖然這個沒太大關係、但是如果你開發的API是公開的,容易遭受到攻擊,影響到網站的狀況

2.API URL and Version
     如果API的變化很大,可以搭配API設計成url名稱
     ex:https://api.github.com/v1  
     ex:https://sample.com/api/v1

3.schema
       返回的格式:建議用JSON,如果要用其他格式在head Accept指定,服務端需要返回正確status code
給詳細說明來

4.從資源中心的URL設計
       在資源來說Restful API的核心概念,所有的操作都是以資源進行,資源就是URL表示,所以要簡潔,
明朗的URL設計,極度重要,可以從一些api部分來說明

/users/:username/repos
/users/:org/repos
/repos/:owner/:repo
/repos/:owner/:repo/tags
/repos/:owner/:repo/branches/:branch

注意:只能有名詞,不能用動詞,URL大小寫敏感,盡可能用小寫字母

.集合盡可能用復數來表示資源,單個資源可以用id來表示
.一個資源有很多URL

5.使用正確的Method

名稱 描述
HEAD 取得HEAD資訊,例如取資源修改日期
GET 取得資料
POST 新增資料
PATCH 局部更新(也可以新增)
PUT 完整更新(覆蓋過去)
DELETE 刪除

範例

  • GET ~url/mermers 或 ~url/members/1
  • POST ~url/members
  • PUT ~url/members/1 (需指定id)
  • PATCH ~url/members/1 (需指定id)
  • DELETE ~url/members/1 (需指定id)

若遇到不符CRUD的狀況

  1. 使用POST,重新寄送POST/resend,為需要動作增加一個使用POST執行動作
  2. 增加控制參數,增加動作相關參數,透過修改參數來控制動作,EX:blog 文章發布,可用上面
    POST /articles/{id}/pulish 或在文章部分加入published:boolean時候,發布就是更新
    PUT /articles/{id}/?published=true
  3. 動作轉換資源,增加一個/gists/:id/star子資源,然後對其進行操作:"喜歡"使用PUT/gists/:id/star,
    取消喜歡使用DELETE /gists/:id/forks可以執行用戶fork action

6.讓Query更自由
    
Query透過參數的方式,來控制返回不同的結果

7.分頁Pagination
        返回某個資源的列表時候,如果返回資料特別多時候EX:url/orders,需要分頁批次回傳資料結果,
分頁技術會用到上面提到url query,可以透過兩個參數返回結果

  • per_page:每頁返回多少資料,沒提供會使用預設的值這個數字也有最大值
  • page:要獲取每一頁資源,預設第一頁

返回資院列表為[(page-1)*per_page, page*per_page)

8.定義合適狀態碼
        HTTP的status code:說明請求大致狀況,定義了完成、處理、錯誤,對於給予客戶端很重要,
狀態碼是三位的整數,下面是比較常見的狀況

  • 2XX:正常處理返回狀態碼
  • 3XX:重定向,請求資源發生變化
  • 4XX:Clinet 發送請求有誤
  • 5XX:服務端異常錯誤
狀態碼 LABEL 解釋
200 OK 請求成功接收並處理,一般回應中都會有body
201 Created 請求已完成,並導致了一個或者多個資源被建立,最常用在POST
建立資源的時候
202 Accepted 請求已經接收並開始處理,但是處理還沒有完成。一般用在異步處
理的情況,回應body 中應該告訴客戶端去哪裡查看動作的狀態
204 No Content 請求已經處理完成,但是沒有訊息要返回,經常用在PUT 更新資源
的時候(客戶端提供資源的所有屬性,因此不需要服務端返回)。

如果有重要的metadata,可以放到頭部返回
301 Moved Permanently 請求的資源已經永久性地移動到另外一個地方,後續所有的請求
都應該直接訪問新地址。

服務端會把新地址寫在
Location頭部字段,方便客戶端使用。
允許客戶端把POST請求修改為GET。
304 Not Modified 請求的資源和之前的版本一樣,沒有發生改變。用來緩存資源,
和條件性請求(conditional request)一起出現
307 Temporary Redirect 目標資源暫時性地移動到新的地址,客戶端需要去新地址進行操
作,但是
不能修改請求的方法。
308 Permanent Redirect 和301類似,除了客戶端不能修改原請求的方法
400 Bad Request 客戶端發送的請求有錯誤(請求語法錯誤,body 資料格式有誤,
body 缺少必須的字段等),導致服務端無法處理
401 Unauthorized 請求的資源需要認證,客戶端沒有提供認證訊息或者認證訊息不
正確
403 Forbidden 服務器端接收到並理解客戶端的請求,但是客戶端的權限不足。
EX:普通用戶想操作只有管理員才有權限的資源。
404 Not Found 客戶端要訪問的資源不存在,鏈接失效或者客戶端偽造URL 的
時候回遇到這個情況
405 Method Not Allowed 服務端接收到了請求,而且要訪問的資源也存在,但是不支持
對應的方法。
服務端
必須返回Allow頭部,告訴客戶端哪些
方法是允許的
415 Unsupported Media Type 服務端不支持客戶端請求的資源格式,一般是因為客戶端在
Content-Type或者Content-Encoding中申明了希望的
返回格式,但是服務端沒有實現。
比如,客戶端希望收到

xml返回,但是服務端支持Json
429 Too Many Requests 客戶端在規定的時間裡發送了太多請求,在進行限流的時候會
用到
500 Internal Server Error 服務器內部錯誤,導致無法完成請求的內容
503 Service Unavailable 服務器因為負載過高或者維護,暫時無法提供服務。服務器端
應該返回
Retry-After頭部,告訴客戶端過一段時間再來重試

    詳細參考:https://httpstatuses.com/

9.錯誤處理:給詳細訊息
       如果出錯的時候,給予response body通過,message詳細訊息。
一般返回代碼,一般返回4xx Bad request結果,結果很模糊,如果給予
message的話,可知道哪裡有問題,迅速修改。

  • 如果Json無法解析,返回Problems parsing Json
  • 缺少必要欄位則,返回402 Unprocessable Entity,除了message
    通過errors 給予哪一個field缺乏,方便調用快速排錯


10.驗證和授權

  • 驗證:確認用戶身分
  • 授權:針對特定資源有操作權限

若沒通過驗證,返回401 Unauthorized 具體錯誤,若沒有授權則返回403 Forbidden,提供詳細錯誤訊息

11.rate limit
    訪問次數不加控制,會造成API濫用,也容易DDOS,依據使用者身分來限流,可防止伺服器壓力。

  • X-RateLimit-Limit: 用戶每小時予許請求最大值
  • X-RateLimit-Remaining:當下時間剩下可用的請求數量
  • X-RateLimit-Rest: 時間重整狀況,到這時間點請求 X-RateLimit-Limit 的值

對於超過流量的請求,可以返回429 Too many requests狀態碼,並附帶錯誤訊息。

12.Hypermedia API
    RestfulAPI設計最好做到Hypermedia,返回結果中提供相關資源連結,例如api.github.com

13.寫出良好的API文件
    API是給人用的,不管公司內部或是公開API都是一樣,遵循規範,若別人不知道怎麼使用開發的API
對每個請求和返回參數給予說明,給一個完整範例,最終目標是能夠依據文件,可以使用你的API或開發
API

參考URL:https://www.footmark.info/programming-language/design/restful-webapi-design-guide/

 

元哥的筆記