Qdrant 新增 REST 端点后如何更新 OpenAPI 规范?从 ytt 文件到 redoc 验证的完整流程
【免费下载链接】qdrantQdrant - High-performance, massive-scale Vector Database and Vector Search Engine for the next generation of AI. Also available in the cloud https://cloud.qdrant.io/项目地址: https://gitcode.com/GitHub_Trending/qd/qdrant
在 Qdrant 的 Rust 代码里新增或修改了一个 REST 端点后,光改代码是不够的:Qdrant 用 OpenAPI 规范描述 API,规范要求“API 变更必须同步到规范文件,且由 CI 强制检查”(见 docs/DEVELOPMENT.md 的API changes → REST一节)。如果不同步,test-consistencyCI 任务会跑 tests/openapi_consistency_check.sh 重新生成规范并与仓库中已提交的文件做 diff,有差异就直接失败。
这篇文章走一遍完整路径:从在openapi/*.ytt.yaml里写端点定义、在src/schema_generator.rs里登记模型,到运行tools/generate_openapi_models.sh生成规范、用 redoc 页面人工验证,最后跑集成测试确认行为。适用前提:你在本地 clone 了 qdrant 仓库,机器上有 Rust 工具链(cargo)、jq和 Docker(生成脚本会构建并运行两个镜像;ytt/yq未安装时脚本自动回退到 Docker 版本)。
规范文件由哪些部分组成
先看清楚生成脚本 tools/generate_openapi_models.sh 的数据流,后面每步修改的文件就都对应上了:
- 端点定义:
openapi/*.ytt.yaml(如 openapi/openapi-service.ytt.yaml),使用 openapi/openapi.lib.yml 提供的 ytt 辅助函数(response、reference、type、array等)描述路径、参数和响应; - 模型定义:
src/schema_generator.rs中的AllDefinitions结构体,通过schemars把 Rust 类型转成 JSON Schema,输出openapi/schemas/AllDefinitions.json,再由tools/schema2openapi容器转成openapi/models.yaml; - 合并:脚本把 9 个
openapi-*.yaml和models.yaml合并为openapi/openapi-merged.yaml/openapi-merged.json,并拷贝到 docs/redoc/master/openapi.json——这就是 redoc 页面加载的文件,也是 CI 一致性检查比对的目标。
第一步:实现 Rust 端点与模型
按照 DEVELOPMENT.md 的第 1 步,先在 Rust 代码里完成端点和模型(lib/api下的 REST 模型、src/actix/api下的路由)。模型类型会被AllDefinitions引用,所以最终要能进 OpenAPI 组件表。
第二步:修改openapi/*.ytt.yaml添加端点
端点按功能归属到对应的 ytt 文件:openapi-main、openapi-collections、openapi-points、openapi-service、openapi-cluster、openapi-quotas、openapi-snapshots、openapi-shards、openapi-shard-snapshots(生成脚本对每个文件逐一执行ytt)。
文件开头统一加载公共库:
#@ load("openapi.lib.yml", "response", "reference", "type", "array")下面是 openapi/openapi-service.ytt.yaml 中现有GET /端点的原文示例,可以照这个结构新增路径、operationId、tags和响应:
paths: /: get: summary: Returns information about the running Qdrant instance description: Returns information about the running Qdrant instance like version and commit id operationId: root tags: - Service responses: "200": description: Qdrant server version information content: application/json: schema: $ref: "#/components/schemas/VersionInfo" "4XX": description: error第三步:在src/schema_generator.rs登记新模型
src/schema_generator.rs 里有一个#[derive(Serialize, JsonSchema)]的AllDefinitions结构体,每个字段对应一个要导出到components/schemas的 Rust 类型:
#[derive(Serialize, JsonSchema)] struct AllDefinitions { a1: CollectionsResponse, a2: CollectionInfo, // ... 现有字段 ... br: segment::data_types::vector_name_config::VectorNameConfig, bs: QuotaStatus, }如果你的新端点引入了新的请求/响应模型,就在该结构体里加一个字段(字段名如a*/b*只是编号习惯,类型必须实现schemars::JsonSchema)。已有模型(如VersionInfo、Usage)已登记,无需重复添加。
第四步:运行生成脚本
在仓库根目录执行:
./tools/generate_openapi_models.sh脚本内部依次做这些动作(脚本有set -e,任一步失败会立即退出):
- 检查本地
ytt;没有则用gerritk/ytt镜像执行,对 9 个openapi-*.ytt.yaml逐个生成openapi/*.yaml; cargo run --package qdrant --features="service_debug" --bin schema_generator生成openapi/schemas/AllDefinitions.json;docker build tools/schema2openapi并用容器把 JSON Schema 转成openapi/models.json,再用yq转成models.yaml(本地无yq时回退到mikefarah/yq镜像);- 合并所有文件为
openapi/openapi-merged.yaml,然后用redocly/openapi-cli:v1.0.0-beta.88容器执行lint openapi-merged.yaml——lint 不过脚本会失败,这是第一道机器校验; - 转成 JSON 并
cp到docs/redoc/master/openapi.json。
副作用说明:该脚本会构建本地 Docker 镜像schema2openapi、拉取/运行上述容器,并覆盖写入openapi/目录下全部生成文件和docs/redoc/master/openapi.json——这些文件本身就是需要随代码一起提交的产物,属于预期行为。前置依赖:Docker、cargo、jq(脚本最后一步用jq格式化,没有本地回退,CI 里是用apt-get install -y clang jq装的,本地需自行保证jq可用)。
第五步:redoc 页面验证
按 DEVELOPMENT.md 的 6、7 步,在docs/redoc目录下起一个静态文件服务:
python -m http.server然后浏览器打开http://localhost:8000/?v=master。?v=master参数不能省:docs/redoc/default_version.js 里默认版本是v1.18.x,不带参数加载的是历史版本快照,只有?v=master才加载刚生成的 docs/redoc/master/openapi.json。检查点:新增端点出现在对应 tag 分组下、请求参数和响应模型渲染正确。
DEVELOPMENT.md 的第 8 步建议再把openapi-merged.yaml贴进 Swagger Editor 做一次可视化校验,确认无告警。
第六步:更新并运行集成测试
DEVELOPMENT.md 第 5 步要求在 tests/openapi 下更新或新增对应测试,然后运行:
uv --project tests run pytest tests/openapi前置条件:本地有一个可访问的 Qdrant 实例在localhost:6333(测试通过 HTTP 直接打本地服务;参考 tests/integration-tests.sh,CI 的做法是先启动./target/debug/qdrant再跑 pytest)。uv未安装时先按 DEVELOPMENT.md 的本地开发一节安装。
别忘了:metrics 白名单与端点总数
DEVELOPMENT.md 的System integration一节指出,新增端点还要把新端点加进src/common/metrics.rs的 metrics 白名单,JWT 相关改动需要过tests/auth_tests。
这一点和一致性检查脚本直接挂钩:tests/openapi_consistency_check.sh 除了比对生成结果与仓库文件(通过则输出 "No diffs found."),还会统计openapi.json中路径总数并与脚本内的EXPECTED_NUMBER_OF_APIS(当前仓库中为69)比较。数量不符时脚本给出的处理建议是:确认新端点在 metrics 端点的白名单(REST_ENDPOINT_WHITELIST/GRPC_ENDPOINT_WHITELIST)中配置正确,一致性恢复后更新脚本里的EXPECTED_NUMBER_OF_APIS。
CI 侧的验收
本地全部通过后,integration-tests工作流的test-consistency任务会以同样的方式复核:构建schema2openapi镜像、装好clang/jq与 protoc 后执行./tests/openapi_consistency_check.sh。它先把docs/redoc/master/openapi.json复制为.diff.openapi.json,重新运行tools/generate_openapi_models.sh,再diff两者——所以生成文件必须提交,而不是只在本地跑一遍。
限制说明
- 生成脚本强依赖 Docker(
schema2openapi镜像构建和 redocly lint 都在容器里执行),无 Docker 环境无法完成第 4 步。 EXPECTED_NUMBER_OF_APIS = 69是当前脚本中的固定值,每新增端点都要同步更新,否则即使 diff 一致也会因数量检查失败。- 本文只覆盖 REST 规范链路;gRPC 侧(
lib/api/src/grpc/proto/*.proto与tests/basic_grpc_test.sh)是 DEVELOPMENT.md 中另一条独立流程,不在本任务范围内。
【免费下载链接】qdrantQdrant - High-performance, massive-scale Vector Database and Vector Search Engine for the next generation of AI. Also available in the cloud https://cloud.qdrant.io/项目地址: https://gitcode.com/GitHub_Trending/qd/qdrant
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考