4. OpenAPI 中的缓存声明

在微服务与 API 网关架构中,缓存是降低延迟、减少后端压力的核心手段。OpenAPI 3.0+ 规范并未直接提供“缓存开关”字段,而是通过 响应对象中的 headers 字段、操作级 responses 定义以及 扩展属性(x-) 来声明缓存策略。本章将系统讲解如何在 OpenAPI 契约中精确表达缓存语义,使客户端与网关能够依据契约自动配置缓存行为。

4.1 缓存声明的基本模型

OpenAPI 中的缓存声明遵循“响应头驱动 + 操作级覆盖”模型。核心思路是:在 API 响应中显式声明 Cache-Control、ETag、Expires 等标准 HTTP 缓存头,并通过操作级配置实现细粒度控制。

关键原则:缓存策略是响应描述的一部分,而非独立字段。所有缓存声明必须嵌入到 responses 对象的 headers 中。
OpenAPI 缓存声明模型 OpenAPI 契约 全局缓存策略(components) 操作级缓存配置(paths) 响应头声明(headers) 扩展属性(x-cache-ttl) Cache-Control / ETag / Expires x-cache-scope / x-cache-ttl

4.2 响应缓存标记:标准 HTTP 头声明

在 OpenAPI 的 responses 对象中,通过 headers 字段声明缓存相关响应头。以下是最常用的三个缓存标记:

响应头 OpenAPI 声明位置 典型值示例 说明
Cache-Control responses.200.headers.Cache-Control public, max-age=3600 定义缓存可见性与有效期
ETag responses.200.headers.ETag "33a64df5" 资源版本标识,用于条件请求
Expires responses.200.headers.Expires Wed, 21 Oct 2025 07:28:00 GMT 绝对过期时间(HTTP/1.0 兼容)
Last-Modified responses.200.headers.Last-Modified Mon, 20 Oct 2025 12:00:00 GMT 资源最后修改时间
最佳实践:优先使用 Cache-Control 而非 Expires。Cache-Control 支持更丰富的指令(如 no-cache、private、s-maxage),且是 HTTP/1.1 标准。

4.3 操作级缓存配置

不同 API 操作对缓存的需求差异很大。例如,GET /users 可能允许公共缓存,而 GET /users/{id}/balance 必须禁止缓存。操作级缓存配置通过在 paths 下每个操作的 responses 中独立声明实现。

paths:
  /users:
    get:
      summary: 获取用户列表
      responses:
        '200':
          description: 成功返回用户列表
          headers:
            Cache-Control:
              schema:
                type: string
                example: public, max-age=300
            ETag:
              schema:
                type: string
                example: "user-list-v1"
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
  /users/{id}/balance:
    get:
      summary: 获取用户余额(敏感数据)
      responses:
        '200':
          description: 成功返回余额
          headers:
            Cache-Control:
              schema:
                type: string
                example: no-store, private
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Balance'
安全警告:涉及用户隐私、金融数据、会话令牌的 API 响应,必须声明 Cache-Control: no-store, private。仅声明 private 而不加 no-store 仍可能被某些代理缓存。

4.4 使用扩展属性定义自定义缓存策略

当标准 HTTP 头无法满足业务缓存需求时(如指定缓存作用域、自定义 TTL 单位),OpenAPI 允许通过 x- 前缀扩展属性来补充缓存语义。

扩展属性 类型 示例值 用途
x-cache-ttl integer 600 自定义缓存过期时间(秒)
x-cache-scope string user / global 缓存作用域:按用户隔离或全局共享
x-cache-key string user:{id}:profile 自定义缓存键模板
x-cache-invalidate array ["POST /users", "PUT /users/{id}"] 触发缓存失效的操作列表
paths:
  /products/{id}:
    get:
      summary: 获取商品详情
      x-cache-ttl: 1200
      x-cache-scope: global
      x-cache-key: "product:{id}:detail"
      responses:
        '200':
          description: 成功
          headers:
            Cache-Control:
              schema:
                type: string
                example: public, max-age=1200
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'

4.5 缓存策略的继承与覆盖

在大型 API 项目中,通常会在 components 中定义通用缓存策略,然后在具体操作中按需覆盖。这种机制减少了重复定义,同时保留了灵活性。

缓存策略继承与覆盖流程 components 默认缓存 Cache-Control: public, max-age=600 GET /products 操作 继承默认策略 生效策略 max-age=600 components 默认缓存 Cache-Control: public, max-age=600 GET /users/me 操作 覆盖为 no-store, private 生效策略 no-store, private 规则:操作级显式声明的缓存头完全覆盖组件级默认值,未声明的头则继承组件定义

4.6 缓存声明清单与校验

为确保缓存策略的完整性与安全性,建议在 API 设计阶段使用以下清单进行自查:

  • 所有 GET 操作是否都声明了 Cache-Control?
  • 敏感数据接口是否使用了 no-store 而非仅 private?
  • 静态资源接口是否设置了合理的 max-age 或 s-maxage?
  • ETag 或 Last-Modified是否与条件请求配合使用?
  • 扩展属性是否在团队内部有统一命名规范?
  • 缓存失效操作是否在 x-cache-invalidate 中正确声明?
工具推荐:使用 spectral 配合自定义规则集,可以自动校验 OpenAPI 契约中是否遗漏了必要的缓存声明。例如,强制要求所有 GET 操作的 200 响应必须包含 Cache-Control 头。

4.7 本章小结