1. OpenAPI 契约基础

1.1 OpenAPI 规范概述

OpenAPI 规范(原 Swagger 规范)是一种用于描述 HTTP API 的标准化、语言无关的接口定义格式。它允许开发者以机器可读的方式定义 API 的端点、请求参数、响应结构、认证方式等元数据,从而在服务提供方与消费方之间建立一份可验证的“契约”。

核心价值:OpenAPI 契约不仅是文档,更是 API 生命周期中设计、开发、测试、部署与缓存策略制定的统一基准。

OpenAPI 规范的主要版本包括:

版本 发布时间 关键特性
Swagger 2.0 2014 奠定基础,广泛采用,支持 RESTful API 基本描述
OpenAPI 3.0 2017 引入 components、oneOf/anyOf、callback、link,增强复用性与表达能力
OpenAPI 3.1 2021 完全兼容 JSON Schema 2020-12,支持 Webhook、license 扩展

在缓存场景中,OpenAPI 契约承担了以下关键角色:

  • 缓存键定义:通过 parameters、headers 明确哪些输入影响缓存键。
  • 缓存时长声明:利用 response headers 或扩展字段标注 Cache-Control、Expires。
  • 缓存失效边界:通过 operationId 与 tags 建立资源依赖关系,指导缓存清理。
OpenAPI 契约在 API 生命周期中的位置 OpenAPI 契约 API 设计 代码生成 测试验证 缓存策略 契约驱动:缓存键、缓存时长、失效规则均从 OpenAPI 定义中推导 避免缓存策略与 API 实现耦合,提升可维护性

1.2 YAML / JSON 语法基础

OpenAPI 规范支持 YAML 和 JSON 两种序列化格式。YAML 因其可读性高、注释友好,成为编写契约的首选;JSON 则常用于程序间交换与存储。

1.2.1 格式对比

特性 YAML JSON
可读性 高(缩进结构,支持注释) 中(括号密集,无注释)
文件大小 较小(无冗余括号) 较大(引号与逗号多)
数据类型 自动推断,支持多行字符串 严格类型,字符串必须引号
工具生态 需注意缩进陷阱 解析器更严格,错误易定位

1.2.2 核心语法示例

以下是一个描述缓存相关 API 的 OpenAPI 3.0 片段,展示 YAML 与 JSON 的对应关系:

# YAML 版本
openapi: "3.0.3"
info:
  title: 缓存示例 API
  version: "1.0.0"
paths:
  /users/{userId}:
    get:
      operationId: getUserById
      parameters:
        - name: userId
          in: path
          required: true
          schema:
            type: string
      responses:
        '200':
          description: 成功返回用户信息
          headers:
            Cache-Control:
              schema:
                type: string
                example: "public, max-age=3600"
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
components:
  schemas:
    User:
      type: object
      properties:
        id:
          type: string
        name:
          type: string
// JSON 等价版本
{
  "openapi": "3.0.3",
  "info": {
    "title": "缓存示例 API",
    "version": "1.0.0"
  },
  "paths": {
    "/users/{userId}": {
      "get": {
        "operationId": "getUserById",
        "parameters": [
          {
            "name": "userId",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "成功返回用户信息",
            "headers": {
              "Cache-Control": {
                "schema": {
                  "type": "string",
                  "example": "public, max-age=3600"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/User" }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "User": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "name": { "type": "string" }
        }
      }
    }
  }
}
YAML 缩进陷阱:YAML 使用空格缩进表示层级,禁止使用 Tab。常见错误是 paths 下的缩进不一致,导致解析失败。建议使用 2 空格缩进,并在编辑器中开启“显示空白字符”。

1.3 API 文档与契约的关系

在传统开发中,“API 文档”与“API 契约”常被混用,但在缓存架构语境下,二者有本质区别:

维度 API 文档 API 契约
目的 人类可读的参考手册 机器可读的接口约定
形式 HTML、PDF、Markdown OpenAPI YAML/JSON、gRPC Proto
可执行性 不可执行,仅用于查阅 可被工具解析、生成代码、驱动测试
缓存关联 通常不包含缓存策略细节 显式声明缓存头、缓存键、失效条件
变更影响 文档滞后于实现 契约变更即接口变更,强制同步

在缓存设计实践中,契约比文档更重要:

  • 缓存键生成:契约中的 parameters、headers 定义直接决定缓存键的组成部分。
  • 缓存策略自动化:通过解析契约中的 Cache-Control、ETag、Last-Modified 声明,可自动配置网关或 CDN 缓存规则。
  • 契约即真相:当缓存策略与契约冲突时,以契约为准,避免因文档过时导致缓存误配置。
API 文档 vs API 契约(缓存视角) API 文档(人类阅读) 缓存描述:文字说明,易过时 缓存键:需人工阅读后手动配置 API 契约(机器可读) 缓存声明:Cache-Control 字段直接解析 缓存键:parameters 自动生成键模板 升级
实战要点:在缓存架构设计中,始终以 OpenAPI 契约为唯一数据源(Single Source of Truth)。文档可以自动从契约生成,但缓存策略的变更必须首先修改契约,再同步到网关或缓存中间件。