Skip to content

OpenAPI 3.1 支持与迁移 ​

English contract · 下载最小 JSON · 下载最小 YAML

本文描述 Java 5.7.7 的 OpenAPI 3.1 契约,具体能力与版本归属见 发布说明和 版本参考。Knife4x Go 使用独立版本, 请查阅 Go 发布说明。本文不改变任何 starter 或默认配置。

支持范围 ​

OpenAPI 的功能集由 major.minor 定义。3.1.x 因此使用同一套 OpenAPI 3.1 feature set,不按 patch 版本拆分能力, 离线导出也复用统一版本判断,不维护私有 patch 白名单。已有 OpenAPI 3.0.x 路径继续保留。 OpenAPI 3.2.x 消费契约见 OpenAPI 3.2 支持矩阵;已发布的 5.7.7 / Knife4x v0.8.6 在本页交付 3.1 范围,3.2 走独立路径。

文档版本UI状态说明
Swagger / OpenAPI 2.0Vue 3兼容维护由 openapi2 starter 提供,不扩展 OAS 3.1 能力
OpenAPI 3.0.xReact支持沿用既有解析、调试、导出与变化提示路径
OpenAPI 3.1.xReact支持使用同一 feature set,并遵守下列产品边界
OpenAPI 3.2.xReact已发布支持不猜测或降级成 3.1 处理;能力与限制见 OpenAPI 3.2 支持矩阵

待发布源码升级

当前源码的 Boot3 Jakarta WebMVC、WebFlux 与独立聚合使用 springdoc 2.9.1,Swagger Jakarta annotations / models / core 统一为 2.2.55。JDK 下限仍为 17;Boot 3.4 线下限为 3.4.7,Boot 3.5 线下限为 3.5.1(共同需要 Framework 6.2.8)。Boot 3.5.0 不满足此下限。 这是待发布源码的要求;下方 5.7.7 及更早版本的历史依赖与兼容记录保持原样。 详见版本对照。

springdoc 生成矩阵 ​

Spring Bootstarter / springdoc生成结果已验证路径证据
Boot 2.xopenapi3 非 Jakarta / springdoc 1.8.0OpenAPI 3.0.x保持既有兼容基线#737
Boot 3.x WebMVCopenapi3 Jakarta / springdoc 2.8.9显式开启 OpenAPI 3.1真实 /v3/api-docs → Java smoke → React / SchemaEngine#737
Boot 3.x WebFluxwebflux Jakarta / springdoc 2.8.9显式开启 OpenAPI 3.1真实 /v3/api-docs → Java smoke → React / SchemaEngine#737
Boot 4.x WebMVCBoot4 starter / springdoc 3.0.3默认或显式 OpenAPI 3.1两种配置都经过端到端验证#737

Boot 3 项目显式生成 OAS 3.1 文档:

yaml
springdoc:
  api-docs:
    version: OPENAPI_3_1

Boot 2 / springdoc 1.8.0 仍生成 OAS 3.0,不能仅修改文档中的 openapi 字符串冒充 OAS 3.1。 完整 starter 版本组合见兼容矩阵。

产品能力矩阵 ​

除非某行另有说明,下表的“支持”指整个 OpenAPI 3.1.x feature set。

能力OAS 3.1.x 行为关键边界已合并证据
单文档与多文档加载入口文档与受控跨文档资源使用同一 3.1 解析会话3.2 文档不进入 3.1 工作流;3.2 消费见3.2 矩阵#682、#689、#727
文档对象与 Webhook支持 paths、components、webhooks 与 3.1 Reference Object;三者至少声明一个Webhook 是入站契约,不等同于普通 Path 请求#717
Schema 方言使用 OAS 3.1 Base Dialect 与 JSON Schema Draft 2020-12 标准词汇不把任意自定义方言解释为标准语义#687、#689
字段树与模型支持 3.1 类型联合、布尔 Schema、const、条件与组合关键字、动态引用等不执行自定义词汇;未知关键字、example 与 extension 的普通载荷保持 opaque,Schema 保留名不参与资源声明预扫描#692、#694、#743
示例保留作者示例并报告不一致;无作者示例时可在预算内生成确定性候选不是通用 JSON Schema 求解器#715
参数调试手填 Path、Query、Header、Cookie 按 3.1 Schema 验证,再按 style / explode 序列化一个参数使用 schema 或一个 content 媒体类型;手填 Cookie 只进入预览 / cURL,浏览器会话来源的 Cookie 由浏览器携带、前端无法校验#716
urlencoded / multipart Body支持结构化字段、encoding、JSON part 与文件元数据检查不读取或验证上传文件内容#728、#730
请求诊断Schema 诊断先阻止发送;同一快照可由用户显式选择“仍然发送”做负向测试不绕过浏览器、安全或资源策略#696、#716、#728
响应诊断按精确状态码、范围或 default 以及媒体类型匹配 JSON 响应 Schema非阻断;不验证响应 Header、Cookie、SSE 或二进制内容#713
单接口导出完整资源图下导出可移植的单接口 OpenAPI JSON;支持 Path 与 Webhook 操作不导出 YAML、ZIP、多文件包或整服务闭包#732、#733
接口变化提示为完整资源图生成 3.1 语义指纹,与 3.0 基线隔离只跟踪 paths 操作,不跟踪 Webhook 或字段级 diff#736
离线文档HTML、Markdown、DOC、DOCX 使用同一不可变 3.1 快照快照入口复用统一 3.1.x 版本判断;资源缺失或诊断未处理时取消,或由用户明确选择降级导出#734

真实 springdoc 到浏览器的总体验收见 #737。

在“Cookie 会话”页面配置并发送登录请求,服务端响应的 Set-Cookie 由浏览器按策略接收, 包括前端无法读取的 HttpOnly Cookie。返回接口调试页后,在 Cookie 页签选择“浏览器会话”, 即可复用浏览器登录会话,无须复制或填写 Cookie 值。

  • 新建 OAS 3.1 调试表单默认使用浏览器会话;旧缓存或历史未记录来源时,按原来的手填模式恢复。
  • 文档中的 Cookie 必填声明仍会显示,但值标为“由浏览器携带(前端未校验)”。前端既不因无法读取 Cookie 而阻断,也不宣称它存在或已通过 Schema 校验;服务端仍按实际会话处理请求。
  • 默认只携带同源会话。API 跨 origin 时,需要选择 include,并由服务端配置允许该页面 origin 和凭据的 CORS;这不会绕过 SameSite、Secure、domain/path 或浏览器 Cookie 策略。跨 origin 不一定跨 site。
  • 预览和历史不包含浏览器实际 Cookie 值;生成的 cURL 带有缺少浏览器会话的说明,独立执行前需要自行配置 Cookie。
  • 切换为“手填 Cookie”后可继续编辑原有值并生成 cURL,手填 Cookie 的浏览器发送仍被阻断。请求头或鉴权配置中残留的显式 Cookie 也会阻断,应先移除这些手填配置。

按分组保存的是登录/退出请求与携带策略,实际 Cookie 按浏览器规则共享,不按 Knife4j 分组或端口隔离。 重置会话配置不会删除浏览器 Cookie;退出会话需要由已配置的服务端退出接口处理。 登录或退出请求的 HTTP 成功提示,仅说明请求成功执行,不代表前端已确认 Cookie 保存、删除或业务登录状态。

JSON Schema 方言与词汇 ​

默认方言 ​

OAS 3.1 Schema Object 是 JSON Schema Draft 2020-12 的方言。根级 jsonSchemaDialect 未声明时, Knife4j 使用 OAS 3.1 Base Dialect:

yaml
jsonSchemaDialect: https://spec.openapis.org/oas/3.1/dialect/base

当前 SchemaEngine 只执行以下两种已知方言的验证语义:

  • https://spec.openapis.org/oas/3.1/dialect/base
  • https://json-schema.org/draft/2020-12/schema

标准与自定义词汇 ​

JSON Schema 2020-12 的 Core、Applicator、Validation、Unevaluated、Meta-Data、Format Annotation 与 Content 标准词汇按方言处理。format 默认是注解,不因浏览器里出现一个格式字符串就自动产生网络、文件或证书能力。

未知扩展关键字和自定义词汇载荷会保留在原始文档中;SchemaEngine 会话成功时,复制与可移植导出也保留这些值, 但 Knife4j 不为它们定义验证、示例生成或字段树语义。

资源声明安全预扫描只进入已知会承载 Schema 的位置:独立 JSON Schema 根、OAS Schema Object、 Draft 2020-12 已知 subschema applicator,以及带版本标记的 Knife4j 可移植资源容器。未知关键字、example 或 extension 的普通数据保持 opaque;其中的 $id、$anchor、$dynamicAnchor、$schema、$vocabulary、$ref 与 $dynamicRef 会原样保留,但不参与资源身份、anchor、方言、vocabulary 或引用预算预扫描。

真正的 Schema 资源根显式选择不受支持的 $schema 或声明自定义 $vocabulary 时,仍会给出资源级不受支持方言诊断, 并阻止依赖完整 Schema 语义的动作;该诊断不会回退到近似方言或执行自定义词汇。预扫描边界的实现与回归证据见 #743。

外部 Schema 资源 ​

SchemaEngine 自身不发起网络请求。外部 $ref、$dynamicRef 和相关基址先由 React UI 的受控资源图加载, 再以不可变 registry 交给解析、验证、导出和指纹流程。

授权范围 ​

  • 默认拒绝全部外部资源;只有文档实际发现并展示的精确 HTTP(S) URI可以被授权。
  • 临时授权只对当前文档世代有效;刷新、切换分组或文档变化后失效。
  • “记住授权”绑定到入口文档的规范化检索 URI 与内容摘要;URI 会保留已解析的 Origin、应用路径与分组查询参数,不会变成主机级通配授权。
  • 持久化记录只保存资源 URI 哈希、脱敏展示值与授权时间,不保存凭据;每份文档最多记住 128 项,序列化记录最多 128 KiB。
  • 设置页的“重置全部本地数据”会撤销已记住的授权;“清理请求缓存”不会撤销资源授权。

请求与凭据 ​

资源请求使用浏览器 CORS、GET、credentials: omit、禁止重定向、无 referrer、无缓存,且不携带 Knife4j Authorize、Cookie、全局参数或业务请求 Header。HTTPS 入口不能降级加载 HTTP 资源,URI 也不能包含 userinfo。

服务端必须返回 200、UTF-8,以及 JSON 或 YAML 媒体类型。跨域服务还必须显式允许当前文档页 Origin。

固定预算 ​

预算上限
单资源解码后大小4 MiB
全部资源解码后大小16 MiB
外部文档数64
引用数10,000
引用深度32
单文档解析节点100,000
全图解析节点250,000
Schema 资源数1,000
并发请求4
单请求超时10 秒
一轮加载总时长30 秒
显式重试每个资源 1 次
YAML alias100

未授权、CORS、媒体类型、解析、重定向、超时或预算失败都会变成结构化、脱敏的资源诊断。 任何依赖完整闭包的动作都会保持不可用,不会偷偷回退到缺引用的结果;文档浏览仍可显示已加载内容和诊断。

浏览器调试边界 ​

OpenAPI 能表达某项契约,不代表浏览器 JavaScript 能安全地发送它。

场景文档展示浏览器调试
TRACEOAS 3.1 Path Item 可展示Fetch 禁止发送
CONNECT / TRACK仅兼容输入到达调试器时展示Fetch 禁止发送;它们不是 OAS 3.1 Path Item 固定字段
GET / HEAD request bodySchema、示例和 cURL 可展示Fetch 禁止带 body
显式 Cookie 参数Schema 验证、序列化预览和 cURL 可展示浏览器禁止脚本设置 Cookie Header,真实发送前阻断
Webhook展示、字段树、离线文档和完整闭包下的单操作导出仅描述入站回调,不从文档页主动发送
mutualTLS识别并展示安全方案UI 不存储或注入客户端证书;应在浏览器、操作系统或受信代理配置
跨域 Schema已授权资源可参与解析仍受 CORS 和上述无凭据策略限制
负向测试可显式忽略当前请求 Schema 诊断只跳过 Schema 阻断,不绕过 Fetch、鉴权或资源策略

这些边界由 浏览器请求限制测试、 文档对象 #717、请求诊断 #696 与资源安全 #727 固化。

从 OpenAPI 3.0 迁移 ​

迁移时应让生成器真正输出 3.1 文档,并逐项检查下列语义,不要只替换 openapi 版本号。

nullable 改为类型联合 ​

yaml
# OpenAPI 3.0
type: string
nullable: true

# OpenAPI 3.1
type: [string, "null"]

布尔 Schema ​

yaml
# 接受任意实例
schema: true

# 拒绝任意实例
schema: false

布尔 Schema 是完整 Schema,不能当成缺失 Schema。

example、examples 与 const ​

yaml
# OpenAPI 3.0 Schema
type: string
enum: [stable]
example: stable

# OpenAPI 3.1 Schema
type: string
const: stable
examples: [stable]

Media Type、Parameter 等 OpenAPI 对象仍可能使用自身的 example / examples 字段;不要把不同对象层级机械合并。

$ref 同级关键字 ​

yaml
# OpenAPI 3.0 Schema 常用包装
allOf:
  - $ref: "#/components/schemas/User"
maxLength: 64

# OpenAPI 3.1 Schema 可以直接组合
$ref: "#/components/schemas/User"
maxLength: 64

这里说的是 Schema Object。OAS 3.1 的 Reference Object 只定义 summary 与 description 两个可用同级字段, 其他同级字段不会被当作目标对象补丁。

原始二进制与编码字符串 ​

yaml
# OpenAPI 3.0 常见原始二进制响应
content:
  application/octet-stream:
    schema:
      type: string
      format: binary

# OpenAPI 3.1 原始二进制响应
content:
  image/png:
    schema:
      contentMediaType: image/png

# OpenAPI 3.1:JSON 字符串里承载 base64,不是原始 body
schema:
  type: string
  contentEncoding: base64
  contentMediaType: image/png

Knife4j 也保留对生成器仍输出 type: string + format: binary 的兼容显示;contentEncoding 表示编码后的字符串, 不能被解释成浏览器文件对象或原始上传体。

Webhook 与双向 TLS ​

yaml
webhooks:
  paymentSettled:
    post:
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PaymentEvent"
      responses:
        "204":
          description: Callback accepted
components:
  securitySchemes:
    ClientCertificate:
      type: mutualTLS

Webhook 描述的是 API 提供方向调用调用方的入站契约;它不是普通 paths 请求。mutualTLS 只声明安全方案, 客户端证书仍由浏览器、操作系统或受信代理持有。

最小有效夹具 ​

仓库提供语义等价、可直接下载的两个最小文档:

它们包含 OAS 3.1 Base Dialect、const、可空类型联合和 Media Type examples,可用于验证加载、字段树、示例与响应诊断。

语言与诊断一致性 ​

本页与 English contract 使用同一版本、能力、安全和迁移边界。React UI 的现有 OAS 3.1 诊断键在中文、英文和日文 locale 中保持同集;locale 一致性测试 会拒绝缺失键、空翻译或插值变量不一致。切换语言不会改变诊断代码或放宽策略。

规范与实现证据 ​

让 OpenAPI 文档更清晰,让接口联调更顺手。