Skip to content
ADP
API Design PrincipleBETA

[ADP-122] Accept

概述

HTTP 請求中的 Accept 標頭指定了對回應可接受的媒體類型。本指南概述了在 API 設計中使用 Accept 標頭的最佳實踐,參考了 RFC 9110、內容協商、HTTP 問題詳情 (RFC 9457) 和 OpenAPI 描述。

指導

  • 客戶端應該(SHOULD)請求 Accept 標頭。

  • 接受標準為:

    • Accept: */* 表示客戶端可以接受任何內容類型 (MIME 類型)
    • Accept: text/* 表示客戶端可以接受文本類型下的任何子類型。
  • 可以(MAY)支持基於版本的協商。

  • 應該(SHOULD)設計您的 API 以支持大多數回應的 application/json 和必要時的二進制格式。

    • 如果客戶端未提供 Accept 標頭,默認為 application/json
  • 應該(SHOULD)始終尊重客戶端在 Accept 標頭中指示的偏好。如果伺服器無法以任何請求的格式提供回應,應(SHOULD)返回 406 Not Acceptable 狀態碼並附帶適當的問題詳情回應。

    http
    HTTP/1.1 406 Not Acceptable
    Content-Type: application/problem+json
    Content-Language: zh-tw
    
    {
      "type": "https://example.com/problems/not-acceptable",
      "title": "Not Acceptable",
      "status": 406,
      "detail": "不支持請求的媒體類型。支持的媒體類型: application/json, application/octet-stream"
    }
  • 應該在伺服器端實現內容協商,以根據 Accept 標頭處理 application/json 和二進制格式。這確保伺服器可以適當回應不同的客戶端請求。參見 內容協商

  • 在 API 文件中清楚記錄支持的媒體類型,以幫助客戶端了解他們可以請求哪些格式以及如何正確使用 Accept 標頭。

  • 可以利用品質值 (q-值) 在多種類型可接受時優先排序媒體類型。這確保伺服器可以返回可用的最優先格式。

語義

參見 內容協商

示例

帶有 Accept 標頭的客戶端請求:

http
GET /resources HTTP/1.1
Host: api.example.com
Accept: application/json, application/octet-stream;q=0.9

伺服器回應處理:

  • application/json 是最優先的媒體類型。

  • 如果伺服器支持 application/json,應該回應:

    http
    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "data": "示例回應"
    }
  • 如果伺服器只支持 application/octet-stream,應該回應:

    http
    HTTP/1.1 200 OK
    Content-Type: application/octet-stream
    
    [二進制數據]
  • 如果不支持請求的媒體類型,伺服器應該回應:

    http
    HTTP/1.1 406 Not Acceptable
    Content-Type: application/problem+json
    
    {
      "type": "https://example.com/problems/not-acceptable",
      "title": "不可接受",
      "status": 406,
      "detail": "不支持請求的媒體類型。支持的媒體類型: application/json, application/octet-stream"
    }

OpenAPI 示例

根據 https://swagger.io/docs/specification/describing-parameters/,您不需要在文件中指定 Accept 標頭,而是指定回應標頭 Content-Type

OpenAPI 規範片段:

要在 OpenAPI 中描述 Accept 標頭,您需要為每個端點指定伺服器可以回應的不同媒體類型。以下是一個示例:

yaml
openapi: 3.0.0
info:
  title: 示例 API
  version: 1.0.0
paths:
  /resources:
    get:
      summary: 獲取資源
      operationId: getResources
      responses:
        '200':
          description: 成功回應
          content:
            'application/json; version=public/v2':
              schema:
                type: object
            application/json:
              schema:
                type: object
            application/octet-stream:
              schema:
                type: string
                format: binary
        '406':
          description: 不可接受
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
components:
  schemas:
    ProblemDetails:
      type: object
      properties:
        type:
          type: string
        title:
          type: string
        status:
          type: integer
        detail:
          type: string

這個 OpenAPI 片段為 GET /resources 端點定義了支持的媒體類型 (application/jsonapplication/octet-stream),並使用問題詳情格式指定了 406 Not Acceptable 回應。

參考

Changelog

  • 2024.09.24 Remove unwanted /api path in the samples