资讯详情

ZITADEL Proto 契约指南:设计约定、Buf 代码生成流水线与下游消费方校验

📅 2026/9/14 20:29:58 | 华诺云谱 👁 阅读
ZITADEL Proto 契约指南:设计约定、Buf 代码生成流水线与下游消费方校验
ZITADEL Proto 契约指南设计约定、Buf 代码生成流水线与下游消费方校验【免费下载链接】zitadelZITADEL - Identity infrastructure, simplified for you.项目地址: https://gitcode.com/GitHub_Trending/zi/zitadel本文围绕 proto/AGENTS.md 这份“面向 AI Agent 的 Proto 工作指南”展开proto/是 ZITADEL 全部 API 契约的唯一来源任何改动都会波及生成的 TS 客户端、Go 后端桩代码和文档站 API 参考。读完后你将掌握 ZITADEL 的 Proto 设计约定版本化、命名、弃用与权限标注、三条已验证的 Nx 生成命令zitadel/proto:generate、zitadel/api:generate、zitadel/docs:generate背后的 buf 配置细节以及 proto 变更之后如何系统地校验zitadel/client、zitadel/api、zitadel/docs等下游消费方。1. proto/ 目录API 契约的唯一事实来源proto/AGENTS.md 开篇给出了一条关键定位proto/定义 ZITADEL 的 API 契约这里的变更会影响生成的客户端generated clients、后端桩代码backend stubs以及文档站的 API 参考。ZITADEL 采用 “API first” 策略——所有功能既可通过 UI 访问也可通过 API 访问而 API 本身用 Protobuf 规格定义再由 Protobuf 规格生成各语言的客户端与服务端代码见 API_DESIGN.md 的 “The Basics” 一节。从目录结构看proto/zitadel/ 下按资源域组织了 150 余个.proto文件覆盖身份基础设施的全部核心域顶层遗留 APIv1.proto、management.proto、instance.proto、user.proto、project.proto、org.proto、idp.proto、settings.proto、text.proto、system.proto、feature.proto、event.proto等。其中v1是旧版基于 context 的 APIcontext based API这一点在 proto/buf.yaml 的 lint ignore 列表中可以得到印证——这 20 多个文件几乎全是 v1 时代的老文件。按资源域划分的 v2 子包org/、user/、project/、group/、member/、session/、saml/、oidc/、idp/、filter/、error/、metadata/、milestone/、quota、webkey/、object/、analytics/、application/、authorization/、internal_permission/、options/、settings/、text/等对应 V2 API 的资源导向resource-oriented设计。自定义代码生成选项protoc_gen_zitadel/目录定义了 ZITADEL 自有的 protoc 插件选项包如zitadel.protoc_gen_zitadel.v2.options下的auth_option是权限标注机制的载体。OpenAPI 文档注解docs/目录配合grpc-gateway的openapiv2注解使用。理解目录结构后需要牢记 proto/AGENTS.md 给出的两条总原则以 API_DESIGN.md 为准命名、版本化、弃用deprecations和资源导向的 API 设计都遵循该文档向后兼容是硬约束除非引入新的主版本同一主版本内的变更必须保持向后兼容。2. 设计约定API_DESIGN.md 的核心规则proto/AGENTS.md 明确把 API_DESIGN.md 指定为命名、版本化与弃用的 Source of Truth因此这些约定是理解proto/变更规范的基础。2.1 版本化Versioning服务与消息使用主版本号major version同一主版本内的任何变更必须向后兼容破坏性变更必须升主版本每个服务独立版本化不同服务可以有不同版本号新建服务从版本2起步因为version 1保留给旧的基于 context 的 API 与服务。2.2 命名约定Naming资源、字段、方法名必须描述性强且一致使用领域术语、避免缩写。例如创建用户或返回用户时使用organization_id而不是org_id或resource_owner请求中的上下文信息作为资源字段显式声明如CreateUserRequest携带organization_id不允许提供非必需的上下文成功响应必须包含操作时间戳命名上以操作为前缀如set_date、creation_date、change_date、deletion_date以及生成的标识符避免跨资源的“万能全局消息”像IDFilter、TimestampFilter、InIDsFilter这类模式固定的类型才应全局化复用。2.3 方法命名Operations and Methods资源上的方法遵循固定动词前缀操作方法名语义要点CreateCreateresource唯一性冲突必须阻断创建并返回错误UpdateUpdateresource多数情况下允许部分更新资源必须已存在DeleteDeleteresource资源不存在时不应返回错误例外必须文档化SetSetresource整体替换创建/更新无需区分时优先用 SetGetGetresource按唯一标识取单个资源不存在必须报错ListListresource应提供过滤、排序与分页选项资源列表上的方法为Add/Remove/Set状态变更类操作按动作命名如Activate/Deactivate、Verify、Send。2.4 权限标注Permission annotationsV2 API 使用 connectRPC 作为主传输协议无需为每个 rpc 手写 REST 路径注解REST 路径注解已弃用仅限存量服务。权限则在 proto 中以自定义选项标注由中间件在调用业务方法前统一检查。实例级权限直接写明option (zitadel.protoc_gen_zitadel.v2.options) { auth_option: { permission: iam.web_key.write } };组织级资源如 users、projects、authorizations的权限无法由 API 层独立判定则标注为authenticated只保证调用者已认证细粒度权限交给被调用的业务函数基于查询的资源检查option (zitadel.protoc_gen_zitadel.v2.options) { auth_option: { permission: authenticated } };这两个选项正是根 buf.gen.yaml 中authoption、zitadel两个自定义插件的输入对应 proto/zitadel/protoc_gen_zitadel/ 包。2.5 分页、过滤与弃用约定分页List 方法应使用PaginationRequestlimit/offset/sorting响应侧用PaginationResponse返回总数。API 必须强制上限——默认 limit 为 100最大 limit 为 1000超出返回错误过滤所有过滤器除非名字本身已表达比较方式否则应提供method字段如TextFilterMethod弃用冗余的 API 方法应弃用且必须将grpc.gateway.protoc_gen_openapiv2.options.openapiv2_operation.deprecated设为true替换建议以 proto 注释形式写在 rpc 上方。这解释了为什么根 buf.gen.yaml 中同时启用了grpc-gateway与openapiv2插件——OpenAPI 产物是文档站 API 参考的来源。2.6 错误处理约定稳定v2服务的每个*_service.proto文件都应导入zitadel/error/v2/error.proto保证反射感知的客户端能解析zitadel.error.v2.ErrorDetail并可靠读取slug字段该规则不适用于v1、v2beta、v3alpha。API 在响应体中返回机器可读错误状态码 错误 slug 人类可读消息 细节如fieldViolations客户端应基于 slug 做自己的翻译与分支处理而不是直接展示 message。3. Buf 工作区破坏性检查与 lint 策略proto/buf.yaml 声明了该模块名为buf.build/zitadel/zitadel依赖三个远端模块commit 锁定在 proto/buf.lock 中buf.build/grpc-ecosystem/grpc-gatewayOpenAPI 注解buf.build/envoyproxy/protoc-gen-validate字段校验规则如min_len/max_lenbuf.build/googleapis/googleapisgoogle.api.http等标准选项breaking检查策略值得注意proto/buf.yamlbreaking: use: - FILE - FIELD_NO_DELETE_UNLESS_NAME_RESERVED - FIELD_NO_DELETE_UNLESS_NUMBER_RESERVED - ENUM_VALUE_NO_DELETE_UNLESS_NAME_RESERVED - ENUM_VALUE_NO_DELETE_UNLESS_NUMBER_RESERVED except: - FIELD_NO_DELETE - ENUM_VALUE_NO_DELETE即只强制“文件级”与“保留reserved机制”层面的破坏性检查普通的FIELD_NO_DELETE被显式豁免——这与 2.2 中“字段删除需走 reserved” 的工程实践一致删字段时应把名字与编号 reserved而不是直接删除。lint采用MINIMAL规则集并忽略了一长串遗留文件action.proto、admin.proto、management.proto、user.proto、v1.proto等见 proto/buf.yaml。可以推断这套配置是对存量 v1 契约的渐进式治理——新文件必须干净老文件豁免 lint 但不豁免破坏性检查。4. 三个已验证的 Nx 生成目标proto/AGENTS.md 列出了三条经过验证Verified的 Nx 命令这是整份指南的核心操作部分目标命令产物底层配置生成 TS Proto 包pnpm nx run zitadel/proto:generatepackages/zitadel-proto的es/、cjs/、types/packages/zitadel-proto/buf.gen.yaml生成 API 资产/桩代码pnpm nx run zitadel/api:generateGo gRPC/connect 桩代码至.artifacts/grpc根 buf.gen.yaml生成 Docs 产物pnpm nx run zitadel/docs:generate文档站 API 参考apps/docs/buf.gen.yaml4.1 zitadel/proto:generate —— TypeScript 包生成该目标定义在 packages/zitadel-proto/project.jsontargets: { generate: { executor: nx:run-commands, cache: true, options: { command: pnpm exec buf generate ../../proto, cwd: packages/zitadel-proto }, inputs: [default, {workspaceRoot}/pnpm-lock.yaml, {workspaceRoot}/proto/**/*], outputs: [{projectRoot}/cjs, {projectRoot}/es, {projectRoot}/types] } }要点在packages/zitadel-proto目录下执行buf generate ../../proto即从包目录视角对根目录的proto/工作区做生成因此对proto/**/*的任何改动都会使该目标缓存失效并触发重新生成packages/zitadel-proto/buf.gen.yaml 启用managed: enabled用本地protoc-gen-es插件生成三套产物es/ESM、cjs/CommonJSjs_import_stylelegacy_commonjs、types/.d.ts全部带include_imports与json_typestrue生成结果即 npm 包zitadel/proto运行时依赖bufbuild/protobufexports映射支持./zitadel/*、./validate/*、./google/*、./protoc-gen-openapiv2/*四组子路径同时提供 ESM/CJS/types 三套解析。packages/zitadel-proto/README.md 给出的使用方式npm install zitadel/protoimport { Organization } from zitadel/proto/zitadel/org/v2/org_pb; const org: Organization | null await getDefaultOrg();注意包名与生成物路径如zitadel/org/v2/org_pb必须与proto/zitadel/org/下的包声明保持一致——这是 proto 变更后 TS 侧最先要校验的消费方。4.2 zitadel/api:generate —— Go 后端桩代码生成该目标在 apps/api/project.json 中体现为先按固定版本把工具链装进本地.artifacts/bin再执行buf generateGOBIN${PWD}/.artifacts/bin/$(go env GOOS)/$(go env GOARCH) go install github.com/bufbuild/buf/cmd/bufv1.67.0 GOBIN${PWD}/.artifacts/bin/$(go env GOOS)/$(go env GOARCH) go install google.golang.org/protobuf/cmd/protoc-gen-gov1.36.11 # ... bash -c PATH${PWD}/.artifacts/bin/$(go env GOOS)/$(go env GOARCH):$PATH buf generate其inputs包含工作区根的buf.gen.yaml与buf.yaml。根 buf.gen.yaml 定义了 8 个插件全部输出到.artifacts/grpc插件作用go/go-grpcProtobuf Go 类型与 gRPC 服务桩代码grpc-gatewayallow_delete_bodytrueconnectRPC/gRPC-gateway 的 HTTP 绑定层openapiv2allow_delete_bodytrueOpenAPI 文档供文档站 API 参考validatelanggoprotoc-gen-validate 生成的 Go 校验代码authoption解析zitadel.protoc_gen_zitadel.v2.options中的auth_option生成权限检查逻辑zitadelZITADEL 自定义插件connect-goconnect-go 的客户端/服务端绑定这条链路的产物直接支撑 Go 后端如 backend/v3 与 internal/api/grpc 下的服务实现。适用前提目标会自行按v1.67.0buf与v1.36.11protoc-gen-go固定安装工具因此无需本机预装 buf但生成后若涉及 Go 代码务必先检查根go.mod见第 5 节。4.3 zitadel/docs:generate —— 文档站 API 参考apps/docs/project.json 的生成目标以 apps/docs/buf.gen.yaml 为输入该文件出现在其inputs列表中产物是文档站的 API 参考内容。这正是 proto/AGENTS.md “Changes here affect … docs API references” 一句的落点proto 注释里的文档说明、权限声明、错误码列表最终都会流进文档站。此外console/project.json 还保留了一个针对 v1 端点的独立生成目标命令为pnpm exec buf generate ../proto --include-imports --include-wkt使用自身buf.gen.yaml说明管理控制台仍消费旧版 v1 契约——修改 v1 文件时这也是一个需要留意的消费方。5. 变更后的工作流校验proto/AGENTS.md 的 “Workflow Notes” 给出两条硬性检查构成 proto 变更的收尾动作校验依赖消费方proto 变更后验证zitadel/client、zitadel/api、zitadel/docs三个下游包。从仓库结构看前两者分别对应 packages/zitadel-client/封装 proto 生成物的 TS 客户端与apps/apiGo 后端Go 工具链前置检查如果在生成或后续修复中触碰了 Go 代码运行任何 Go 工具go build、go test、go mod tidy等之前先检查根目录的go.mod。由于zitadel/api:generate会把桩代码输出到.artifacts/grpc并在GOBIN下安装 buf/protoc-gen-gogo.mod 中相关模块与替换replace配置是否正确直接决定 Go 侧能否编译通过。配合第 2 节的向后兼容原则一次合格的 proto 变更流程可以概括为按 API_DESIGN.md 约定修改.proto命名、版本、弃用注释、权限选项、validate.rules约束用buf breaking语义约束自证兼容删字段/枚举值时改为 reserved而非直接删除对应 proto/buf.yaml 的 breaking 规则依次或按需运行pnpm nx run zitadel/proto:generate、pnpm nx run zitadel/api:generate、pnpm nx run zitadel/docs:generate利用 Nx 缓存机制只对真正受proto/**/*变更影响的目标重新生成编译/类型检查zitadel/clientTS 侧、zitadel/apiGo 侧先看go.mod、zitadel/docs文档侧确认无破坏性遗漏。6. 小结为什么这份 AGENTS 指南重要proto/AGENTS.md 篇幅不长但它把 ZITADEL “API first” 架构中最高频、最容易出错的一环压缩成了可执行清单契约在proto/规范在 API_DESIGN.md产物由三个 Nx 目标分别生成给 TS 客户端、Go 后端与文档站变更之后必须回到消费方验证Go 侧动手前先查go.mod。对贡献者或 Agent 而言掌握这条“proto 为源、buf 生成、多消费方校验”的流水线就掌握了安全修改 ZITADEL API 契约的完整路径。【免费下载链接】zitadelZITADEL - Identity infrastructure, simplified for you.项目地址: https://gitcode.com/GitHub_Trending/zi/zitadel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。