2. OpenAPI 规范基础:OpenAPI 3.0 简介、路径定义、请求/响应模型、参数校验规则

2.1 OpenAPI 3.0 简介

OpenAPI 规范(原 Swagger 规范)是一种用于描述 HTTP API 的标准化接口描述语言。OpenAPI 3.0 是目前广泛采用的版本,它允许开发者以机器可读的 YAML 或 JSON 格式定义 API 的端点、输入输出、认证方式及校验规则。在异步导出场景中,OpenAPI 规范是定义“参数校验失败”响应结构的基础契约。

核心价值: 一份 OpenAPI 3.0 文档同时驱动 API 文档生成、客户端 SDK 生成、服务端参数校验框架(如 express-openapi-validator)以及测试用例。

2.2 路径定义与操作对象

每个 API 端点通过 paths 对象定义,包含一个或多个 HTTP 方法(operation)。路径支持模板参数(如 /export/{taskId}),这些参数是参数校验的第一道关卡。

paths:
  /export:
    post:
      summary: 发起异步导出任务
      operationId: createExportTask
      parameters:
        - name: X-Request-Id
          in: header
          required: true
          schema:
            type: string
            pattern: '^[a-f0-9\-]{36}$'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExportRequest'
      responses:
        '202':
          description: 任务已接受
        '400':
          description: 参数校验失败
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ValidationErrorResponse'

2.3 请求/响应模型

OpenAPI 3.0 使用 components/schemas 定义可复用的数据模型。在异步导出中,请求模型定义导出参数,响应模型定义校验失败的结构。

模型类型 示例字段 校验关注点
ExportRequest dateFrom, dateTo, format, filters 日期范围、枚举值、嵌套对象必填
ValidationErrorResponse code, message, errors[] 错误码、人类可读消息、字段级错误列表
FieldError field, reason, rejectedValue 字段路径、失败原因、被拒绝的值
components:
  schemas:
    ExportRequest:
      type: object
      required: [dateFrom, dateTo, format]
      properties:
        dateFrom:
          type: string
          format: date
        dateTo:
          type: string
          format: date
        format:
          type: string
          enum: [csv, xlsx, json]
    ValidationErrorResponse:
      type: object
      required: [code, message, errors]
      properties:
        code:
          type: string
          example: VALIDATION_ERROR
        message:
          type: string
          example: 请求参数校验失败
        errors:
          type: array
          items:
            $ref: '#/components/schemas/FieldError'
    FieldError:
      type: object
      required: [field, reason]
      properties:
        field:
          type: string
          example: dateFrom
        reason:
          type: string
          example: 日期格式无效
        rejectedValue:
          type: string
          example: 2025-13-01

2.4 参数校验规则

OpenAPI 3.0 提供多层次的校验规则,覆盖路径参数、查询参数、请求头、请求体。在异步导出中,校验失败必须返回统一的 400 Bad Request 响应。

设计原则: 所有校验失败响应必须使用相同的 ValidationErrorResponse 模型,确保客户端解析逻辑一致。

2.4.1 校验规则分类

  • 类型校验: type(string, integer, boolean, array, object)
  • 格式校验: format(date, date-time, email, uuid, uri)
  • 约束校验: minimum, maximum, minLength, maxLength, pattern
  • 枚举校验: enum 限定允许值列表
  • 必填校验: required 数组定义必填字段
  • 嵌套校验: allOf, oneOf, anyOf 组合模式

2.4.2 校验失败响应结构

当参数校验失败时,服务端必须返回包含字段级错误详情的响应。以下是一个典型的校验失败响应示例:

HTTP/1.1 400 Bad Request
Content-Type: application/json

{
  "code": "VALIDATION_ERROR",
  "message": "请求参数校验失败",
  "errors": [
    {
      "field": "dateFrom",
      "reason": "日期格式无效,应为 yyyy-MM-dd",
      "rejectedValue": "2025-13-01"
    },
    {
      "field": "format",
      "reason": "枚举值无效,允许值: csv, xlsx, json",
      "rejectedValue": "pdf"
    }
  ]
}

2.5 参数校验流程(SVG)

下图展示了从请求到达至校验失败响应的完整流程:

OpenAPI 参数校验流程 OpenAPI 参数校验流程 客户端请求 路径/方法匹配 参数校验 类型 / 格式 / 约束 / 枚举 / 必填 校验失败 → 400 响应 校验通过 → 业务处理 说明:校验失败响应必须包含 errors 数组,每个元素描述一个字段的失败原因

2.6 校验规则与响应映射(SVG)

下表以图形方式展示不同校验规则与响应中 errors[].reason 的映射关系:

校验规则与响应映射 校验规则 → 响应错误映射 校验规则 类型校验 (type) 格式校验 (format) 枚举校验 (enum) 必填校验 (required) 响应 errors[].reason 示例 "字段类型无效,期望 integer,收到 string" "日期格式无效,应为 yyyy-MM-dd" "枚举值无效,允许值: csv, xlsx, json" "必填字段缺失: dateFrom"

2.7 最佳实践与避坑

常见陷阱: 不要在校验失败响应中返回 HTTP 200 状态码。即使业务逻辑部分成功,只要参数校验失败,必须使用 400 状态码。客户端依赖状态码判断是否重试或展示错误。
  • 统一错误模型: 所有校验失败响应使用同一个 ValidationErrorResponse 模型,避免不同端点返回不同结构。
  • 字段路径清晰: field 使用点号路径(如 filters.dateRange.start)便于客户端定位嵌套字段。
  • 拒绝值保留: 在 rejectedValue 中保留用户传入的原始值,方便调试和用户提示。
  • 国际化准备: message 和 reason 使用英文或中文均可,但建议在 API 网关层统一处理国际化。
  • 性能考虑: 参数校验应在请求进入业务逻辑之前完成,避免无效请求消耗数据库或文件系统资源。

2.8 本章小结