Google Ads API 协议定义与 Bazel GAPIC 构建指南:从 Proto 描述符到多语言客户端生成
【免费下载链接】googleapisPublic interface definitions of Google APIs.项目地址: https://gitcode.com/GitHub_Trending/go/googleapis
本指南以 google/ads/googleads/README.md 为骨架,结合 googleapis 仓库中google/ads/googleads目录下的真实协议缓冲(Protocol Buffer)定义与实验性 Bazel 构建文件,系统讲解 Google Ads API 的接口定义组织方式、如何使用官方客户端库或自行基于 gRPC 构建客户端,以及如何借助 Bazel 目标从 proto 描述符生成多语言 GAPIC 客户端。读完本文,你将理解v22~v25版本目录的构成逻辑,掌握googleads_gapic.yaml、googleads_grpc_service_config.json、googleads_v25.yaml三类配置的职责,并能在无官方客户端库的语言中依据 proto 定义直接开发调用 Google Ads API 的程序。
Google Ads API 协议定义概览
google/ads/googleads目录存放的是 Google Ads API 的协议缓冲(protocol buffer)定义,以及一组标注为experimental的 Bazel 构建文件。协议缓冲是 Google 定义结构化数据的语言无关序列化机制,Google Ads API 的全部请求、响应、资源模型与错误类型都由.proto文件描述。
在 google/ads/googleads 目录下,API 按大版本(major version)组织为平行目录:
v22/v23/v24/v25/
每个版本目录内部结构完全一致,以v25为例(见 google/ads/googleads/v25):
| 目录/文件 | 职责 |
|---|---|
services/ | 每个服务一个.proto,定义 gRPC 方法与请求/响应消息,例如GoogleAdsService、CampaignService、AdGroupService |
resources/ | 资源模型定义(customer.proto、campaign.proto、ad_group.proto等),对应可在 API 中读取或变更的实体 |
enums/ | 枚举类型定义(如response_content_type.proto、summary_row_setting.proto) |
errors/ | 错误类型定义,如GoogleAdsFailure的引用来源 |
common/ | 共享的复合类型定义(metrics.proto、segments.proto) |
actions/ | 自定义操作(actions)的定义,例如 google/ads/googleads/v25/actions/book_campaigns.proto、quote_campaigns.proto |
googleads_gapic.yaml | GAPIC 代码生成器配置(语言包名、长时运行轮询策略等) |
googleads_grpc_service_config.json | gRPC 服务级配置(超时、重试策略) |
googleads_v25.yaml | Google API Service 描述(服务清单、认证 scope、HTTP 路由规则) |
BUILD.bazel | Bazel 构建文件,定义 proto 库与各语言 GAPIC 生成目标 |
注:
v25的BUILD.bazel中引用的resources_proto位于//google/ads/googleads/v25/resources,该目录虽未在上层列表中逐项展开,但属于版本目录的标准组成部分,与 google/ads/googleads/v25/BUILD.bazel 中的依赖声明一致。
这种"一版本一目录"的布局,使不同版本可以长期共存,客户端可以根据账号能力选择调用特定版本,也为各语言 GAPIC 客户端按版本独立生成提供了基础。
官方客户端库与首次调用
README 明确指出,对绝大多数开发者而言,应优先使用官方客户端库。Google Ads API 为 Java、Ruby、PHP、Python、.NET 等语言提供了官方客户端库,这些库正是基于本文所述的 GAPIC 产物构建,并在其上增加了大量性能与易用性增强(如重试、分页封装、类型安全的资源名构造等)。因此:
- 使用官方客户端库是强烈推荐的接入方式;
- 若你的语言没有官方客户端库,则需以
google/ads/googleads/v*/services/*.proto为参考,自行构造 gRPC 请求。
无论走哪条路,首次调用都需要完成账号认证、OAuth scope 授权并获取 API token。从本仓库的 googleads_v25.yaml 可以看到,Google Ads API 的全部方法统一使用 OAuth 2.0 认证,其 canonical scope 为https://www.googleapis.com/auth/adwords——这是构造请求头、配置客户端凭据时必须使用的授权范围。文档中的 Quickstart 指南会引导你完成从创建开发者 token、配置 OAuth 到发出第一次Search调用的完整流程。
理解核心服务入口:GoogleAdsService
虽然版本目录下有上百个*Service,但最核心的入口是GoogleAdsService,它同时承担查询与写入两类职责,定义见 google/ads/googleads/v25/services/google_ads_service.proto。
Search / SearchStream:GAQL 查询
Search与SearchStream接受一个 GAQL(Google Ads Query Language)查询字符串,返回匹配的资源行:
rpc Search(SearchGoogleAdsRequest) returns (SearchGoogleAdsResponse) { option (google.api.http) = { post: "/v25/customers/{customer_id=*}/googleAds:search" body: "*" }; option (google.api.method_signature) = "customer_id,query"; } rpc SearchStream(SearchGoogleAdsStreamRequest) returns (stream SearchGoogleAdsStreamResponse) { option (google.api.http) = { post: "/v25/customers/{customer_id=*}/googleAds:searchStream" body: "*" }; option (google.api.method_signature) = "customer_id,query"; }两点值得注意:
- HTTP 映射:二者分别映射为
POST /v25/customers/{customer_id}/googleAds:search与...:searchStream,customer_id为路径参数,body: "*"表示请求体即完整 JSON 请求。这意味着即使不使用 gRPC,也可以直接以 REST JSON 方式调用。 - 流式差异:
Search一次性返回分页结果;SearchStream是服务端流式接口,returns (stream ...)表明结果会分批持续推送,适合大批量数据导出场景。
Mutate:原子事务与临时资源名
Mutate将"变更类"操作聚合为一次调用(见 google/ads/googleads/v25/services/google_ads_service.proto#L340-L364),其文档明确列出了相对于逐个调用 mutate 方法的三个优势:
- 原子事务(Atomic Transactions):一批操作要么全部成功、要么全部失败,避免多步变更中途失败导致账号状态不一致;
- 临时资源名(Temp Resource Names):在一次事务内可以用占位资源名引用"即将创建"的资源,实现创建后立即关联(例如先建 campaign 再建 campaign budget);
- 更低延迟:相比串行调用多次 mutate,一次批量调用可减少往返次数。
Mutate本质上是对一系列 mutate 方法的包装,但注意 README 与源码注释均说明:只有支持原子事务的资源才可进入该调用,因此它无法替代所有单个服务的 mutate 方法。
版本目录的配置文件三件套
每个版本目录都附带三类配置文件,它们共同决定了"proto 描述符如何变成可用的 API 客户端"。
googleads_gapic.yaml:GAPIC 代码生成配置
以 google/ads/googleads/v25/googleads_gapic.yaml 为例,它声明config_schema_version: 2.0.0,为 Java、PHP 等语言指定生成包名(如com.google.ads.googleads.v25.services、Google\Ads\GoogleAds\V25\Services),并为特定方法覆盖生成策略。例如OfflineUserDataJobService.RunOfflineUserDataJob被标记为长时运行操作(long-running operation),并给出轮询参数:
| 参数 | 值 | 含义 |
|---|---|---|
initial_poll_delay_millis | 300000 | 初始轮询延迟 5 分钟 |
max_poll_delay_millis | 3600000 | 最大轮询间隔 1 小时 |
poll_delay_multiplier | 1.25 | 每次轮询间隔按 1.25 倍指数退避增长 |
total_poll_timeout_millis | 43200000 | 总轮询超时 12 小时 |
这正是离线用户数据任务(如受众上传)这类"提交后异步执行"操作所需的客户端侧轮询语义——它告诉生成的 GAPIC 客户端如何等待任务完成。
googleads_grpc_service_config.json:超时与重试
google/ads/googleads/v25/googleads_grpc_service_config.json 为 gRPC 生成客户端提供统一的服务级调用策略。文件通过methodConfig列出该版本全部服务的名称(从AccountBudgetProposalService到YouTubeVideoUploadService),并统一应用:
"timeout": "14400s", "retryPolicy": { "initialBackoff": "5s", "maxBackoff": "60s", "backoffMultiplier": 1.3, "retryableStatusCodes": ["UNAVAILABLE", "DEADLINE_EXCEEDED"] }含义拆解:
- 单次调用超时 4 小时(
14400s),适用于大量数据查询; - 重试初始退避 5 秒,最大退避 60 秒,退避倍率 1.3;
- 仅对
UNAVAILABLE(服务暂不可用)与DEADLINE_EXCEEDED(超时)两类 gRPC 状态码进行重试,避免对业务错误(如参数非法)做无意义重试。
从源码结构看,该 JSON 被BUILD.bazel中所有语言的 GAPIC 目标(Java、PHP、C#、Ruby、Python、Node.js)作为grpc_service_config参数引用,说明这份重试/超时语义会原样进入各语言生成客户端的通道配置。
googleads_v25.yaml:服务描述与认证
google/ads/googleads/v25/googleads_v25.yaml 是标准的google.api.Service描述文件(config_version: 3,服务名googleads.googleapis.com),包含:
- apis 清单:逐条列出该版本暴露的全部 100+ 个服务(googleads_v25.yaml#L6-L116),这是版本能力的"目录总表";
- types 清单:声明跨服务共享的公开类型,如
GoogleAdsFailure、BatchJob.BatchJobMetadata、OfflineUserDataJobMetadata; - documentation:API 摘要——"Manage your Google Ads accounts, campaigns, and reports with this API.",并强调该 API 面向大而复杂的账号与广告系列管理场景(googleads_v25.yaml#L125-L131);
- http.rules:为
google.longrunning.Operations提供 REST 路由映射,例如POST /v25/{name=customers/*/operations/*}:cancel,使长时运行操作同样可通过 REST 管理(googleads_v25.yaml#L133-L146); - authentication.rules:为每个方法(含通配符形式如
AudienceInsightsService.*)声明 OAuth scope,统一为https://www.googleapis.com/auth/adwords(googleads_v25.yaml#L148-L260)。
Bazel 构建文件:从 Proto 到多语言 GAPIC
README 明确声明:仓库中的 Bazel 构建文件是experimental的,包结构与内容可能随时变更,由此生成的 API 客户端不属于官方支持产品。但官方客户端库正是建立在这些 GAPIC 产物之上;对于想深入理解客户端库内部实现、或需要构建自定义 gRPC 客户端的开发者,这些构建文件是极有价值的参考。
以 google/ads/googleads/v25/BUILD.bazel 为例,构建体系自底向上分为三层:
第一层:Proto 库
proto_library( name = "googleads_proto", srcs = [], deps = [ "//google/ads/googleads/v25/common:common_proto", "//google/ads/googleads/v25/enums:enums_proto", "//google/ads/googleads/v25/errors:errors_proto", "//google/ads/googleads/v25/resources:resources_proto", "//google/ads/googleads/v25/services:services_proto", "//google/ads/googleads/v25/actions:actions_proto", ], ) proto_library_with_info( name = "googleads_proto_with_info", deps = [":googleads_proto"], )googleads_proto聚合六个子包为统一的 proto 库;googleads_proto_with_info则在其上附带源码信息(用于生成文档与代码示例)。注意顶层BUILD.bazel通过exports_files导出了googleads_grpc_service_config.json与所有*.yaml,供各语言目标引用。
第二层:各语言 GAPIC 库
BUILD.bazel为 Java、PHP、C#、Ruby、Python、Node.js 六种语言分别声明了*_gapic_library目标。它们共享三类输入:googleads_gapic.yaml(生成配置)、googleads_grpc_service_config.json(通道策略)、googleads_v25.yaml(服务描述)。以 Java 为例:
java_gapic_library( name = "googleads_java_gapic", srcs = [":googleads_proto_with_info"], gapic_yaml = "googleads_gapic.yaml", grpc_service_config = ":googleads_grpc_service_config.json", service_yaml = "googleads_v25.yaml", deps = [ "//google/ads/googleads/v25/common:common_java_proto", "//google/ads/googleads/v25/enums:enums_java_proto", "//google/ads/googleads/v25/resources:resources_java_proto", "//google/ads/googleads/v25/services:services_java_grpc", "//google/ads/googleads/v25/services:services_java_proto", "//google/ads/googleads/v25/actions:actions_java_grpc", "//google/ads/googleads/v25/actions:actions_java_proto", ], )从源码结构看,这里值得关注的差异点:
- PHP使用
migration_mode = "NEW_SURFACE_ONLY"与generate_snippets = False,且通过plugin_args = ["aggregate_metadata=google.ads.googleads"]生成聚合元数据; - Ruby走
ruby_ads_gapic_library专用规则,并通过extra_protoc_parameters设置 gem 名google-ads-googleads、默认主机googleads.googleapis.com以及命名空间覆盖Googleads -> GoogleAds; - Python通过
opt_args指定python-gapic-name=googleads与warehouse-package-name=google-ads,即生成的 Python 包发布名; - Node.js指定
main_service = "GoogleAdsService"与package = "google.ads.googleads.v25",并生成 metadata。
第三层:可发布的分发包
每个语言最终聚合为*_assembly_pkg(如googleads-java、googleads-php、googleads-csharp、googleads-ruby、googleads-py、googleads-nodejs),把 GAPIC 库与其依赖的 proto/grpc 产物打包,作为后续构建发布物(Gradle 工程、Composer 包、NuGet 包、gem、wheel、npm 包)的入口。
附带测试目标
Java 目标还附带测试:googleads_java_gapic_suite运行com.google.ads.googleads.v25.services.CampaignServiceClientTest(google/ads/googleads/v25/BUILD.bazel#L78-L84)。这说明生成的 GAPIC 客户端并非只做静态代码生成,还会生成并运行针对核心服务(如 CampaignService)的客户端测试,验证生成的调用逻辑可用。
在无官方客户端库的语言中自行开发
如果你使用的编程语言没有官方客户端库,README 给出的路径是:参考 API Concepts Guide,并以本仓库的 proto 定义为准绳来构造请求。具体做法通常包含四步:
- 生成桩代码:用
protoc(配合grpc插件)编译目标版本的services/*.proto、resources/*.proto及其依赖,生成该语言的 gRPC 桩与消息类。proto 之间的import路径均以仓库根为基准(如import "google/ads/googleads/v25/enums/response_content_type.proto"),编译时需把仓库根目录加入-I包含路径。 - 实现认证:为每个 RPC 附加 OAuth 2.0 访问令牌,scope 固定为
https://www.googleapis.com/auth/adwords(依据 googleads_v25.yaml);在 REST 场景下同样通过 Bearer token 携带。 - 调用核心方法:查询走
GoogleAdsService.Search/SearchStream,写入走Mutate;大批量异步任务(如离线用户数据)走OfflineUserDataJobService,并按googleads_gapic.yaml中的轮询参数等待长时运行操作完成。 - 处理错误:错误消息结构以
errors/目录中的类型为准,顶层公共错误类型GoogleAdsFailure已声明在googleads_v25.yaml的types清单中;同时自行实现googleads_grpc_service_config.json规定的超时与重试语义(4 小时超时、对UNAVAILABLE/DEADLINE_EXCEEDED重试)。
需要再次强调的是:由于 Bazel 构建文件为 experimental,自行基于 GAPIC 生成客户端仅适合作为参考与定制起点;在生产环境中,README 强烈建议使用官方客户端库以获得完整支持、性能优化与持续维护。
参与反馈与版本演进
Google Ads API 的迭代节奏较快,仓库中v22到v25四个版本并存即为佐证:每个大版本都会带来新资源、新枚举与新服务方法,同时旧版本仍保留供迁移。对 API 本身(新特性请求、Bug 报告)与客户端库生态(如希望新增某语言的官方支持)的反馈,可提交到官方 Google Ads API 论坛;而本仓库的代码贡献则遵循仓库根目录的 CONTRIBUTING.md 与 CODE_OF_CONDUCT.md。
总结
围绕 google/ads/googleads/README.md,本仓库提供了 Google Ads API 的完整协议定义与一套实验性的多语言 GAPIC 构建流水线:
- 协议定义:
v22~v25按版本组织,services/、resources/、enums/、errors/、common/、actions/各司其职; - 三种配置文件:
googleads_gapic.yaml控制代码生成细节,googleads_grpc_service_config.json统一超时与重试,googleads_v25.yaml声明服务清单、HTTP 路由与 OAuth scope; - Bazel 构建:从
googleads_proto到六语言*_gapic_library,再到可发布的*_assembly_pkg,展示了官方客户端库的底层生成链路; - 接入选择:优先使用官方客户端库;无官方库的语言可基于 proto 定义自行生成 gRPC 客户端,并按本文给出的认证、调用与错误处理要点实现。
无论你是想深入理解 Google Ads 客户端库的内部机制,还是在冷门语言中自研接入层,google/ads/googleads目录都是一份权威的、可直接对照的接口契约。
【免费下载链接】googleapisPublic interface definitions of Google APIs.项目地址: https://gitcode.com/GitHub_Trending/go/googleapis
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考