alltools.one
API
2025-06-05
7 min
alltools.one Team
APIRESTJSONResponse FormatBest Practices

API 回應格式:打造一致性 API 的最佳實踐

不一致的 API 回應是前端開發者最常抱怨的問題之一。當每個端點回傳的資料結構都不同時,用戶端程式碼就會充斥各種特殊處理邏輯。一致的回應格式能提升開發者體驗、減少錯誤,並讓你的 API 具有自我描述的能力。

回應封裝結構

將每個回應包裝在一致的結構中:

成功回應(單一資源)

{
  "data": {
    "id": "user_123",
    "name": "Alice",
    "email": "alice@example.com",
    "createdAt": "2024-01-15T10:30:00Z"
  },
  "meta": {
    "requestId": "req_abc123"
  }
}

成功回應(集合)

{
  "data": [
    { "id": "user_123", "name": "Alice" },
    { "id": "user_456", "name": "Bob" }
  ],
  "meta": {
    "total": 142,
    "page": 1,
    "perPage": 20,
    "requestId": "req_def456"
  }
}

錯誤回應

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [
      { "field": "email", "message": "Invalid email format" }
    ]
  },
  "meta": {
    "requestId": "req_ghi789"
  }
}

核心原則:用戶端始終在最上層檢查 dataerror。絕不要在同一個回應中混合成功資料與錯誤資訊。

使用我們的 JSON 驗證器來驗證你的回應格式。

HTTP 狀態碼

正確使用狀態碼 — 它們是用戶端首先檢查的資訊:

成功狀態碼

狀態碼使用時機
200 OKGET 成功、PUT/PATCH 成功
201 CreatedPOST 建立了新資源
204 No ContentDELETE 成功(無回應主體)

用戶端錯誤狀態碼

狀態碼使用時機
400 Bad Request請求語法格式錯誤
401 Unauthorized缺少或無效的身份驗證
403 Forbidden已驗證但未授權
404 Not Found資源不存在
409 Conflict資源狀態衝突(重複)
422 Unprocessable語法正確但語義有誤
429 Too Many Requests超過速率限制

伺服器錯誤狀態碼

狀態碼使用時機
500 Internal Server Error非預期的伺服器故障
502 Bad Gateway上游服務故障
503 Service Unavailable暫時過載或維護中

錯誤回應設計

良好的錯誤回應能幫助開發者快速除錯:

{
  "error": {
    "code": "RESOURCE_NOT_FOUND",
    "message": "User with ID 'user_999' not found",
    "details": [],
    "documentationUrl": "https://api.example.com/docs/errors#RESOURCE_NOT_FOUND"
  },
  "meta": {
    "requestId": "req_xyz789",
    "timestamp": "2024-01-15T10:30:00Z"
  }
}

規則

  • code 是機器可讀的(固定字串,而非 HTTP 狀態碼)
  • message 是人類可讀的(可以修改而不影響用戶端)
  • details 提供驗證失敗時的欄位級別錯誤
  • requestId 讓支援團隊能在日誌中追蹤該請求

分頁模式

偏移量分頁

簡單且支援跳轉到任意頁面:

{
  "data": ["..."],
  "meta": {
    "page": 2,
    "perPage": 20,
    "total": 142,
    "totalPages": 8
  },
  "links": {
    "first": "/api/users?page=1&per_page=20",
    "prev": "/api/users?page=1&per_page=20",
    "next": "/api/users?page=3&per_page=20",
    "last": "/api/users?page=8&per_page=20"
  }
}

游標分頁

更適合即時資料和大型資料集:

{
  "data": ["..."],
  "meta": {
    "hasNext": true,
    "hasPrev": true
  },
  "links": {
    "next": "/api/users?cursor=eyJpZCI6MTQzfQ&limit=20",
    "prev": "/api/users?cursor=eyJpZCI6MTIzfQ&limit=20&direction=prev"
  }
}

日期與時間

始終使用帶有時區資訊的 ISO 8601 格式:

{
  "createdAt": "2024-01-15T10:30:00Z",
  "updatedAt": "2024-01-15T14:22:33+00:00",
  "expiresAt": "2024-12-31T23:59:59Z"
}

絕對不要使用:

  • Unix 時間戳(模糊不清:秒還是毫秒?)
  • 不帶時區的本地日期
  • 自訂格式如 MM/DD/YYYY

如需了解更多時間戳處理方式,請參閱我們的 Unix 時間戳指南

Null 與缺失欄位

兩種常見做法:

包含 null(明確表示):

{ "name": "Alice", "avatar": null, "bio": null }

省略缺失欄位(稀疏表示):

{ "name": "Alice" }

建議:在你的 API 中保持一致。明確的 null 對型別語言更好(用戶端知道該欄位存在)。稀疏表示適合頻寬受限的環境。

回應版本控制

當回應格式變更時,為你的 API 做版本控制:

GET /api/v2/users/123

需要版本控制的破壞性變更:

  • 移除欄位
  • 變更欄位型別
  • 重新命名欄位
  • 變更回應封裝結構

無需版本控制的非破壞性變更:

  • 新增欄位
  • 新增端點
  • 新增列舉值

常見問題

是否應該將成功回應包裝在 data 鍵中,還是直接回傳資源?

使用 data 封裝可為所有回應提供一致的結構,並保留空間讓中繼資料、分頁和連結與資料並存。直接回傳資源對單一資源端點更為簡潔。大多數現代 API 為了一致性而採用封裝方式。

批次操作中的部分失敗該如何處理?

回傳 200 狀態碼,並在 data 物件中同時包含成功和失敗的結果。使用 207 Multi-Status(WebDAV)是另一種選擇,但在 REST API 中較不常用。

相關資源

Published on 2025-06-05
API Response Formats: Best Practices for Consistent APIs | alltools.one