Skip to content
ADP
API Design PrincipleBETA

[ADP-113] PUT

概述

HTTP PUT 方法用於更新或替換指定 URI 的資源。它是一個冪等方法,意味著多個相同的請求應該與單個請求具有相同的效果。PUT 通常用於使用新狀態更新資源。

指導原則

  • 必須(MUST)確保多個相同的 PUT 請求與單個請求具有相同的效果。
  • 可以(MAY)在回應主體中包含更新後的資源表示。
  • 必須(MUST)在 URI 中使用資源的唯一標識符。
  • DRAFT 如果資源識別需要,可以(MAY)支持使用複雜鍵。
  • 必須(MUST)用請求主體中提供的新狀態替換整個資源。
  • 應該(SHOULD)驗證並拒絕嘗試部分更新的請求。
  • 必須(MUST)驗證傳入請求的完整性和正確性。
  • 必須(MUST)使用 HTTP Problem Details 格式(RFC 9457)返回錯誤回應。
  • 關於請求體中省略的屬性,有兩個選擇:
    • 可以(MAY)選擇不重置屬性(設置為 null),因為這樣做可能不方便,但需要記錄這個決策。
    • 必須明確指定省略的屬性將從對象中刪除,並在文件中告知使用者。
  • 當不確定時,應該(SHOULD)優先使用 PATCH 進行部分更新。
  • 如果識別屬性不是服務器擁有的話,對空資源進行PUT操作可能(MAY)會被解釋為POST請求,實際上創建了一個新的資源。
  • 可以(MAY)使用If-Match/If-None-MatchETag實現PUT操作,以防止意外操作。

回應

  • 如果更新成功並包含更新後資源的表示,必須(MUST)返回 200 OK 狀態碼。
  • 如果 PUT 請求新建了資源,必須(MUST)返回 201 Created。
  • 如果請求是針對異步操作且成功,應該(SHOULD)返回 202 Accepted。
  • 如果更新成功但不包含表示,必須(MUST)返回 204 No Content 狀態碼。
  • 如果資源不存在,必須(MUST)返回 404 Not Found 狀態碼。
  • 如果更新過程中存在衝突,應該(SHOULD)返回 409 Conflict 狀態碼。

錯誤回應

所有錯誤回應必須(MUST)使用 RFC 9457 中定義的 HTTP Problem Details 格式。例如:

http
HTTP/1.1 404 Not Found
Content-Type: application/problem+json

{
  "type": "https://example.com/problems/not-found",
  "title": "Not found",
  "status": 404,
  "detail": "無法找到請求的資源。",
  "instance": "/users/123"
}

示例

  1. 更新用戶資料

    http
    PUT /users/123
    Content-Type: application/json
    
    {
      "name": "張三",
      "email": "zhangsan@example.com",
      "age": 30
    }

    回應

    http
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "id": 123,
      "name": "張三",
      "email": "zhangsan@example.com",
      "age": 30
    }
  2. 替換現有產品

    http
    PUT /products/456
    Content-Type: application/json
    
    {
      "name": "新產品名稱",
      "price": 99.99,
      "stock": 50
    }

    回應

    http
    HTTP/1.1 204 No Content
  3. 資源未找到(使用 Problem Details)

    http
    PUT /products/789
    Content-Type: application/json
    
    {
      "name": "不存在的產品",
      "price": 0,
      "stock": 0
    }

    回應

    http
    HTTP/1.1 404 Not Found
    Content-Type: application/problem+json
    
    {
      "type": "https://example.com/problems/not-found",
      "title": "Not found",
      "status": 404,
      "detail": "ID 為 789 的產品不存在。",
      "instance": "/products/789"
    }

最佳實踐

  • 考慮在更新資源之前使用 GET 請求檢索當前狀態。
  • 對於大型資源,考慮使用分塊傳輸編碼。
  • 實現適當的並發控制機制,如 ETag 和條件請求。參閱 ETag以及條件請求
  • DRAFT 可(MAY)記錄所有 PUT 操作以便審計和回滾。
  • 在整個 API 中為類似的錯誤條件使用一致的 Problem Details 類型。

安全考慮

  • 實現適當的身份驗證和授權機制。
  • 驗證和淨化輸入數據以防止注入攻擊。
  • 使用 HTTPS 加密傳輸中的敏感數據。
  • 確保 Problem Details 回應不會洩露敏感資訊。

參考資料