2. OpenAPI 规范基础:OpenAPI Specification (OAS) 版本演进、核心结构、YAML/JSON 语法

OpenAPI 规范(OAS)是定义 HTTP API 的标准接口描述语言,它独立于编程语言,既可供人类阅读,也可被机器解析。在分布式任务调度平台中,OAS 是契约一致性的核心载体——调度中心与执行器、管理端与 SDK 之间的所有交互,都依赖一份精确的 OAS 文档来约束请求/响应结构、状态码和错误模型。

2.1 OAS 版本演进与选型建议

OAS 经历了从 Swagger 2.0 到 OpenAPI 3.0/3.1 的演进。不同版本在表达能力、复用机制和 JSON Schema 兼容性上存在显著差异。

特性 Swagger 2.0 OpenAPI 3.0.x OpenAPI 3.1.x
基础格式 Swagger 规范 OpenAPI 规范 OpenAPI 规范
JSON Schema 兼容 自定义子集 接近 JSON Schema Draft 5 完全兼容 JSON Schema 2020-12
请求体描述 body / formData requestBody 对象 requestBody 对象
多态/组合 discriminator 有限 oneOf / anyOf / allOf 原生 JSON Schema 组合
示例支持 单 example examples 多实例 examples 多实例
路径参数 parameters 内联 parameters + pathItems parameters + pathItems
Webhook 不支持 不支持 原生 webhooks 对象
选型建议: 对于新建的分布式任务调度平台,推荐直接使用 OpenAPI 3.1.x。它原生支持 JSON Schema 2020-12,可以精确描述任务参数、回调负载和分片配置中的复杂嵌套结构,减少自定义扩展标记。

2.2 OAS 核心结构:从根对象到路径

一份完整的 OAS 文档由顶层对象和若干核心区块组成。以下 SVG 展示了 OAS 3.1 的顶层结构及其关系:

OpenAPI 3.1 核心结构图 OpenAPI 对象 info servers paths components /tasks /executors schemas parameters 说明: paths 定义所有 API 端点及其操作;components 提供可复用的 schema、参数、响应等构件。

OAS 文档的顶层字段必须包含 openapi(版本声明)、info(元信息)和 paths(路径定义)。servers 和 components 为推荐字段,webhooks、tags、externalDocs 为可选字段。

2.3 YAML / JSON 语法与选择

OAS 支持 YAML 和 JSON 两种序列化格式。在分布式任务调度平台的实践中,YAML 因可读性高、支持注释、适合人工编写而成为首选;JSON 则常用于程序生成和网络传输。

2.3.1 语法对比

特性 YAML JSON
可读性 高,缩进层级清晰 中,括号嵌套较密集
注释 支持 # 行注释 不支持
多行字符串 支持 | / > 需转义 \n
引用/锚点 支持 & / * 不支持
解析速度 较慢(需处理缩进) 较快
工具生态 Swagger Editor、Redoc 原生支持 所有工具均支持

2.3.2 典型 YAML 示例:任务提交接口

以下代码片段展示了一个分布式任务调度平台中“提交任务”端点的 OAS 3.1 定义,使用 YAML 格式:

openapi: "3.1.0"
info:
  title: 分布式任务调度平台 API
  version: "2.0.0"
  description: 用于任务提交、查询、停止及执行器管理的契约接口

servers:
  - url: https://api.scheduler.example.com/v2
    description: 生产环境

paths:
  /tasks:
    post:
      summary: 提交新任务
      operationId: submitTask
      tags:
        - 任务管理
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TaskSubmitRequest'
      responses:
        '201':
          description: 任务创建成功
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaskSubmitResponse'
        '400':
          description: 请求参数校验失败
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '503':
          description: 调度服务暂不可用

components:
  schemas:
    TaskSubmitRequest:
      type: object
      required:
        - taskName
        - executorType
        - command
      properties:
        taskName:
          type: string
          description: 任务名称,全局唯一
          example: "data-export-20250321"
        executorType:
          type: string
          enum: [shell, python, docker, http]
          description: 执行器类型
        command:
          type: string
          description: 执行命令或入口脚本
        timeout:
          type: integer
          description: 超时时间(秒)
          default: 300
        retryCount:
          type: integer
          description: 失败重试次数
          default: 0
    TaskSubmitResponse:
      type: object
      properties:
        taskId:
          type: string
          description: 调度系统生成的唯一任务 ID
        status:
          type: string
          enum: [queued, running, completed, failed]
    ErrorResponse:
      type: object
      properties:
        code:
          type: string
        message:
          type: string
关键实践: 在 components/schemas 中定义所有数据模型,路径操作中仅通过 $ref 引用。这种“引用优先”策略可以避免路径定义膨胀,并确保同一模型在多个端点间保持契约一致。

2.4 路径与操作:HTTP 方法的契约映射

每个路径下可包含一个或多个 HTTP 方法操作(get、post、put、delete、patch 等)。每个操作必须定义 operationId(唯一标识)、parameters(路径/查询/头参数)、requestBody(仅适用于 post/put/patch)和 responses(至少一个成功响应)。

以下 SVG 展示了路径 /tasks/{taskId} 上 GET 和 DELETE 两个操作的内部结构:

路径操作结构示例:/tasks/{taskId} /tasks/{taskId} GET parameters: taskId responses: 200, 404 DELETE parameters: taskId responses: 204, 404 注意: GET 返回任务详情(200),DELETE 返回空体(204)。两个操作共享同一个路径参数 taskId,但响应模型不同。

2.5 数据模型与复用机制

components/schemas 是 OAS 契约一致性的基石。在分布式任务调度平台中,以下模型通常被定义为可复用的 Schema:

  • Task:任务核心属性(ID、名称、类型、状态、优先级、创建时间)
  • Executor:执行器注册信息(名称、地址、标签、心跳时间)
  • TaskLog:任务执行日志(行号、时间戳、级别、内容)
  • Pagination:分页请求(page、size、sort)和分页响应(total、items)
  • ErrorResponse:统一错误结构(code、message、traceId)
常见陷阱: 避免在路径操作中直接内联复杂对象。如果两个端点返回相同的“任务状态”结构,但一个内联定义、另一个使用 $ref,当状态字段变更时,两个端点将产生契约漂移。始终优先使用 $ref 引用 components/schemas 中的定义。

2.6 契约一致性检查清单

在编写或评审 OAS 文档时,可使用以下清单快速验证基础质量:

检查项 要求 严重等级
版本声明 openapi 字段必须为 3.1.0 或 3.0.3 致命
operationId 唯一性 所有操作的 operationId 不可重复 致命
响应定义完整性 每个操作至少包含一个成功响应(2xx) 致命
参数类型约束 路径参数必须声明 in: path 且 required: true 致命
Schema 复用率 重复出现 2 次以上的结构应抽取到 components/schemas 建议
示例填充 关键字段应提供 example 或 examples 建议