Skip to content
ADP
API Design PrincipleBETA

[ADP-357] 長時間運行的任務

概述

本文件概述了在 RESTful API 中處理長時間運行任務的指導方針和最佳實踐。長時間運行的任務是指可能需要大量時間才能完成,無法在典型的請求-回應週期內處理的操作。

指導方針

  • 必須(MUST)為成功創建的任務返回 HTTP 狀態碼 202 Accepted。
  • 必須(MUST)在回應標頭中返回 Location,以向客戶端提供有關已創建任務的資訊。
  • 作業創建後,有兩個作法可提供額外的結果。
    • 可(MAY)在作業完成時返回 Location,生成一個與作業不同的URI的新資源。
    http
    HTTP/1.1 200 OK
    Location: https://my.dev/v1/jobs/job-id/results
    Content-Location: https://my.dev/v1/jobs/job-id
    
    {
      "jobId": "123e4567-e89b-12d3-a456-426614174000",
      "status": "COMPLETED",
      "createdAt": "2023-04-01T12:00:00Z",
      "updatedAt": "2023-04-01T12:10:00Z"
    }
    • 可(MAY)在作業資源中包含一個 response 欄位。

    TIP

    這個方法受到opensearch和elasticsearch的啟發,它們都直接在搜索作業中嵌入了回應。 設計理念是啟用搜索作業的輪詢,並為API用戶提供部分搜索結果的更新。根據你的用例決定。如果你的目標是提供類似於elasticsearch/opensearch的API,你可以(MAY)採用這個設計。然而,它們的設計並不完全符合目前的ADP。記住最佳實踐原則:如果你(作為API設計師)認為這是行業標準,則採用它。如果你對設計不滿意,試著發想一個更好的設計,並貢獻回ADP。

  • 必須(MUST)在任務資源中包含狀態屬性(property)。
  • 應該(SHOULD)為每個任務使用唯一標識符(例如 UUID)。
  • 可以(MAY)附加 Sunset 標頭,以指示任務完成後資源將被移除的時間。
  • 如果任務失敗,應(SHOULD)提供問題詳細資訊對象(與 RFC 9457 兼容)或錯誤 JSON。
  • 可(MAY)考慮允許客戶端在需要時取消正在運行的任務
    • DRAFT 可以(MAY)設計使用 DELETE 動詞對應取消任務。
    http
    DELETE /jobs/{job-id}
  • 可(MAY)考慮實現通知系統(例如 webhooks)以在任務完成時通知客戶端
  • 應(SHOULD)實施適當的安全措施,確保客戶端只能訪問自己的任務資源
  • DRAFT 可(MAY)附加 Retry-After 用以指出應該在多久後重新查詢作業狀態。

實現細節

任務創建

當客戶端啟動長時間運行的任務時,服務器應:

  1. 接受請求並創建任務資源
  2. 返回 202 Accepted 狀態碼
  3. 在 Location 標頭中包含已創建任務資源的 URI

回應示例:

http
HTTP/1.1 202 Accepted
Location: https://api.my.dev/v1/jobs/123e4567-e89b-12d3-a456-426614174000

任務資源

任務資源應至少包含以下資訊:

  • 唯一標識符
  • 任務的當前狀態
  • 創建和最後更新的時間戳

任務資源示例:

json
{
  "jobId": "123e4567-e89b-12d3-a456-426614174000",
  "status": "RUNNING",
  "createdAt": "2023-04-01T12:00:00Z",
  "updatedAt": "2023-04-01T12:05:00Z"
}

任務狀態

任務狀態應為以下之一:

  • PENDING: 任務已排隊但尚未開始
  • RUNNING: 任務當前正在處理中
  • COMPLETED: 任務已成功完成
  • FAILED: 任務遇到錯誤無法完成

錯誤處理

如果任務失敗,請使用問題詳細資訊對象提供詳細的錯誤資訊:

http
GET /jobs/123e4567-e89b-12d3-a456-426614174000 HTTP/1.1

HTTP/1.1 200 OK
Content-Type: application/json

{
  "jobId": "123e4567-e89b-12d3-a456-426614174000",
  "status": "FAILED",
  "createdAt": "2023-04-01T12:00:00Z",
  "updatedAt": "2023-04-01T12:10:00Z",
  "problem": {
    "type": "https://example.com/problems/job-execution-error",
    "title": "任務執行錯誤",
    "status": 500,
    "detail": "任務執行期間發生意外錯誤"
  }
}

OpenAPI 3.1.0 示例

以下是使用 OpenAPI 3.1.0 記錄長時間運行任務 API 的示例:

yaml
openapi: 3.1.0
info:
  title: 長時間運行任務 API
  version: 1.0.0

paths:
  /jobs:
    post:
      summary: 創建新任務
      operationId: createJob
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/JobRequest'
      responses:
        '202':
          description: 已接受
          headers:
            Location:
              schema:
                type: string
              description: 已創建任務資源的 URI
  
  /jobs/{jobId}:
    get:
      summary: 獲取任務狀態
      operationId: getJobStatus
      parameters:
        - name: jobId
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: 成功回應
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Job'

components:
  schemas:
    JobRequest:
      type: object
      properties:
        # 定義任務請求屬性
    
    Job:
      type: object
      properties:
        jobId:
          type: string
          format: uuid
        status:
          type: string
          enum: [PENDING, RUNNING, COMPLETED, FAILED]
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        problem:
          $ref: '#/components/schemas/Problem'
    
    Problem:
      type: object
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
        status:
          type: integer
        detail:
          type: string

參考資料

Changelog

  • 2024.10.30 Add more reference; add result design for long running task