[ADP-137] Range
概述
HTTP 中的 Range 標頭允許客戶端請求資源的特定部分,而不是整個資源。這對於有效處理大型數據集、提供部分回應和支持可恢復下載非常有用。雖然主要用於字節範圍,但在 RESTful API 中也可以適用於其他單位,如項目或記錄。然而,為確保正確實現和客戶端-服務器交互,需要仔細的文件說明和遵守標準。
指導
不應(SHOULD NOT)用 Range 標頭進行分頁。請參考 ADP-312: 分頁了解首選做法。
如果必須使用基於 Range 的分頁,請清楚說明所使用的單位。
基於 Range 的分頁示例:
```http GET /users Range: users=0-9 206 Partial Content Accept-Ranges: users Content-Range: users 0-9/200 ```
在上面的例子中,單位是
users
。它應該是資源/實體類型的複數形式。
對於更複雜的用例,Range 標頭可以(MAY)指定字節範圍,詳見 RFC 9110 規範。
字節範圍值示例:
``` bytes=-500 bytes=9500- bytes=0-0,-1 bytes=0-999,4500-5499,-1000 ```
如果無法滿足請求的 Range 或不支持指定的單位,服務器應(SHOULD)回應 HTTP 狀態 416(Range Not Satisfiable)。
使用 HTTP Problem Details(RFC 9457)提供更多錯誤資訊。
```http GET /images/{image-id} HTTP/1.1 Range: bytes=500-509 HTTP/1.1 416 Range Not Satisfiable Content-Type: application/problem+json Content-Range: */200 { "type": "/problems/range-not-satisfiable", "title": "Range Not Satisfiable", "status": 416, "detail": "無法滿足請求的範圍", "instance": "/images/{image-id}" } ```
示例
考慮一個用於檢索大文件部分內容的 API 端點。以下是如何實現 Range 標頭進行部分內容檢索:
http
GET /largefile HTTP/1.1
Range: bytes=0-999
HTTP/1.1 206 Partial Content
Accept-Ranges: bytes
Content-Range: bytes 0-999/5000
如果客戶端請求無法滿足的範圍:
http
GET /largefile
Range: bytes=6000-6999
HTTP/1.1 416 Range Not Satisfiable
Content-Type: application/problem+json
Content-Range: /5000
{
"type": "https://example.com/problems/range-not-satisfiable",
"title": "Range Not Satisfiable",
"status": 416,
"detail": "無法滿足請求的範圍",
"instance": "/largefile"
}
OpenAPI 示例
要在 OpenAPI 規範中記錄 Range 標頭的使用,可以使用以下示例:
yaml
openapi: 3.1.0
info:
title: Large File API
version: 1.0.0
paths:
/largefile:
get:
summary: Retrieve a range of bytes from a large file
parameters:
- name: Range
in: header
required: false
schema:
type: string
example: bytes=0-999
description: Range header to request a specific range of bytes.
responses:
'206':
description: Partial Content
headers:
Accept-Ranges:
description: Supported units for the Range header
schema:
type: string
Content-Range:
description: The range of bytes returned
schema:
type: string
content:
application/octet-stream:
schema:
type: string
format: binary
'416':
description: Range Not Satisfiable
headers:
Content-Range:
description: The actual range of the resource
schema:
type: string
content:
application/problem+json:
schema:
type: object
properties:
type:
type: string
example: "https://example.com/problems/range-not-satisfiable"
title:
type: string
example: "Range Not Satisfiable"
status:
type: integer
example: 416
detail:
type: string
example: "The requested range cannot be satisfied"
instance:
type: string
example: "/largefile"
'200':
description: Successful response (if no Range header is used)
'400':
description: Bad Request (if the Range header is malformed)
避免重複定義已知標頭
根據 ADP-767,你應該(SHOULD)使用已經定義好的共用標頭檔案或至少使用 #/components/headers
,以避免重新定義所有已知標頭。
語意
請參閱 ADP-351: 範圍請求。