定義 API 時的注意事項

隨著開發經驗增加,定義的 API 和越過的坑也越來越多,今天來總結一下定義 API 時需要注意的幾件事情,希望未來自己不要再忘記。

常用的 HTTP 方法

  • GET: 請求資料
  • POST: 新增
  • PUT: 更新(取代舊資源)
  • PATCH: 更新(只更新資源的其中一部分)
  • DELETE: 刪除

HTTP 狀態碼

  • 資訊回應: 100~199
  • 成功回應 : 200~299
  • 重定向 : 300~399
  • 客戶端錯誤 : 400~499
  • 伺服器端錯誤 : 500~599
常用狀態碼:
  • 200 OK: 成功
  • 201 Created: 建立成功
  • 301 Moved Permanently: 永久重定向
  • 302 Found: 暫時性重定向
  • 400 Bad Request: 請求錯誤、參數錯誤
  • 401 Unauthorized: 需要授權、需要 Token, key
  • 403 Forbidden: 沒有權限、無效授權
  • 415 Unsupported Media Type: 型別錯誤、參數錯誤、請求格式錯誤
  • 500 Internal Server Error: 伺服器錯誤、伺服器端出現例外

回應訊息

執行成功通常會回應 200,body 留空或是回傳資料。例如新增使用者成功,回傳新增成功的使用者資料:
    
{
  "id": 1,
  "name": "Ruyut",
  "email": "a@ruyut.com"
}
    

發生錯誤時除了 HTTP 狀態碼以外,通常還會在 body 中再放置錯誤代號和訊息、詳細資訊,方便開發人員除錯。例如新增使用者時缺少 name, email 欄位資料:
    
{
  "error": {
    "code": "INVALID_PARAMETERS",
    "message": "參數錯誤",
    "details": [
      {
        "field": "name",
        "message": "使用者名稱為必填"
      },
      {
        "field": "email",
        "message": "電子郵件為必填"
      }
    ]
  }
}
    

RESTful API

平時使用的 API 有可能是以功能命名,例如:
    
/deleteUser?name=小明
/createUser
/findUser?name=小明
/cuserv3/a=1
    

好一點的我們可以透過路徑名稱猜得出來,但各個路徑間可能毫無關聯,非常依賴 API 說明文件,而 RESTful API 則是利用 HTTP 協議,例如上面的 HTTP 方法和 HTTP 狀態碼。只要大家都依照這個規範,其他開發人員就可以很容易的了解各 API 的用途

例如:
    
GET: /users/1		取得主鍵為 1 的使用者資料
POST: /users		建立新使用者
PUT: /users/1		更新主鍵為 1 的使用者資料
DELETE: /users/1	刪除主鍵為 1 的使用者

GET: /user?min_age=18&max_age=30	查詢年齡 18 至 30 的使用者
    

API 夾帶資料

API 常見的傳輸資料有以下幾種方式:
  • Query String: 在網址列中傳遞,缺點是長度有限制、資料內容很容易被查看
  • Header: 常放置驗證資訊、資料型態、編碼格式等
  • body: 最常見的放置資料位子,通常以 JSON 或是 XML 格式存放資料,在 GET 方法中通常無法夾帶 body
  • Form Data: 表單資料就是 Form Data
  • Multipart Form: 傳輸檔案用

Query String

Query String 的內容會接在網址後面以 ? 開始,多筆資料中間直接使用 & 連接,假設網址為 /user ,K1 資料為 V1, K2 資料為 V2 ,則: /user?K1=V1&K2=V2

若資料為陣列型態也有兩種傳輸方式:
/users?id=1,2,3,4,5

或是:
/users?id=1&id=2&id=3&id=4&id=5

註: 依據 RFC 3986 標準 Query String 長度是無上限的,但是依照不同瀏覽器和網頁伺服器有不同的 Query String 長度限制,常見的限制為 2048。若資料真的太長可以考慮使用 POST 方法並將資料放置在 Body 中,不過這並不是 RESTful API 的最佳實踐,但是個不錯的解決方式。

命名

欄位名稱通常以全小寫,單字間以底線連接,例如: image_url, access_token 。當然,這不是強制的,要使用 - 串接或是駝峰式命名都沒有問題,只是千萬要小心空白,不好處理。

時間資料格式

傳輸中若有日期時間,建議使用 ISO 8601 標準的格式:

日期: YYYY-MM-DD ,例: 2023-04-08
時間: HH:mm:ss,例: 18:01:02
日期和時間: YYYY-MM-DDTHH:mm:ss 例: 2023-04-08T18:01:02

包含時區的時間:
UTC 時間: YYYY-MM-DDTHH:mm:ssZ 例: 2023-04-08T18:01:02Z
指定時區時間: YYYY-MM-DDTHH:mm:ss±HH:mm 例: 2023-04-08T18:01:02+08:00

註:在標準格式中使用 T 用來表示時間分隔

撰寫文件

定義完 API 後記得反覆測試並撰寫文件,可以使用例如 OpenAPI(Swagger) 等工具,最好附上測試範例,方便使用 API 的開發人員方便測試。

參考資料:
mdn - HTTP request methods
mdn - HTTP response status codes

留言