Google Ads API 协议定义与 Bazel GAPIC 构建指南:从 Proto 描述符到多语言客户端生成
2026/9/16 10:50:54 网站建设 项目流程

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 客户端。读完本文,你将理解v22v25版本目录的构成逻辑,掌握googleads_gapic.yamlgoogleads_grpc_service_config.jsongoogleads_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 方法与请求/响应消息,例如GoogleAdsServiceCampaignServiceAdGroupService
resources/资源模型定义(customer.protocampaign.protoad_group.proto等),对应可在 API 中读取或变更的实体
enums/枚举类型定义(如response_content_type.protosummary_row_setting.proto
errors/错误类型定义,如GoogleAdsFailure的引用来源
common/共享的复合类型定义(metrics.protosegments.proto
actions/自定义操作(actions)的定义,例如 google/ads/googleads/v25/actions/book_campaigns.proto、quote_campaigns.proto
googleads_gapic.yamlGAPIC 代码生成器配置(语言包名、长时运行轮询策略等)
googleads_grpc_service_config.jsongRPC 服务级配置(超时、重试策略)
googleads_v25.yamlGoogle API Service 描述(服务清单、认证 scope、HTTP 路由规则)
BUILD.bazelBazel 构建文件,定义 proto 库与各语言 GAPIC 生成目标

注:v25BUILD.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 查询

SearchSearchStream接受一个 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"; }

两点值得注意:

  1. HTTP 映射:二者分别映射为POST /v25/customers/{customer_id}/googleAds:search...:searchStreamcustomer_id为路径参数,body: "*"表示请求体即完整 JSON 请求。这意味着即使不使用 gRPC,也可以直接以 REST JSON 方式调用。
  2. 流式差异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.servicesGoogle\Ads\GoogleAds\V25\Services),并为特定方法覆盖生成策略。例如OfflineUserDataJobService.RunOfflineUserDataJob被标记为长时运行操作(long-running operation),并给出轮询参数:

参数含义
initial_poll_delay_millis300000初始轮询延迟 5 分钟
max_poll_delay_millis3600000最大轮询间隔 1 小时
poll_delay_multiplier1.25每次轮询间隔按 1.25 倍指数退避增长
total_poll_timeout_millis43200000总轮询超时 12 小时

这正是离线用户数据任务(如受众上传)这类"提交后异步执行"操作所需的客户端侧轮询语义——它告诉生成的 GAPIC 客户端如何等待任务完成。

googleads_grpc_service_config.json:超时与重试

google/ads/googleads/v25/googleads_grpc_service_config.json 为 gRPC 生成客户端提供统一的服务级调用策略。文件通过methodConfig列出该版本全部服务的名称(从AccountBudgetProposalServiceYouTubeVideoUploadService),并统一应用:

"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 清单:声明跨服务共享的公开类型,如GoogleAdsFailureBatchJob.BatchJobMetadataOfflineUserDataJobMetadata
  • 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"]生成聚合元数据;
  • Rubyruby_ads_gapic_library专用规则,并通过extra_protoc_parameters设置 gem 名google-ads-googleads、默认主机googleads.googleapis.com以及命名空间覆盖Googleads -> GoogleAds
  • Python通过opt_args指定python-gapic-name=googleadswarehouse-package-name=google-ads,即生成的 Python 包发布名;
  • Node.js指定main_service = "GoogleAdsService"package = "google.ads.googleads.v25",并生成 metadata。

第三层:可发布的分发包

每个语言最终聚合为*_assembly_pkg(如googleads-javagoogleads-phpgoogleads-csharpgoogleads-rubygoogleads-pygoogleads-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 定义为准绳来构造请求。具体做法通常包含四步:

  1. 生成桩代码:用protoc(配合grpc插件)编译目标版本的services/*.protoresources/*.proto及其依赖,生成该语言的 gRPC 桩与消息类。proto 之间的import路径均以仓库根为基准(如import "google/ads/googleads/v25/enums/response_content_type.proto"),编译时需把仓库根目录加入-I包含路径。
  2. 实现认证:为每个 RPC 附加 OAuth 2.0 访问令牌,scope 固定为https://www.googleapis.com/auth/adwords(依据 googleads_v25.yaml);在 REST 场景下同样通过 Bearer token 携带。
  3. 调用核心方法:查询走GoogleAdsService.Search/SearchStream,写入走Mutate;大批量异步任务(如离线用户数据)走OfflineUserDataJobService,并按googleads_gapic.yaml中的轮询参数等待长时运行操作完成。
  4. 处理错误:错误消息结构以errors/目录中的类型为准,顶层公共错误类型GoogleAdsFailure已声明在googleads_v25.yamltypes清单中;同时自行实现googleads_grpc_service_config.json规定的超时与重试语义(4 小时超时、对UNAVAILABLE/DEADLINE_EXCEEDED重试)。

需要再次强调的是:由于 Bazel 构建文件为 experimental,自行基于 GAPIC 生成客户端仅适合作为参考与定制起点;在生产环境中,README 强烈建议使用官方客户端库以获得完整支持、性能优化与持续维护。

参与反馈与版本演进

Google Ads API 的迭代节奏较快,仓库中v22v25四个版本并存即为佐证:每个大版本都会带来新资源、新枚举与新服务方法,同时旧版本仍保留供迁移。对 API 本身(新特性请求、Bug 报告)与客户端库生态(如希望新增某语言的官方支持)的反馈,可提交到官方 Google Ads API 论坛;而本仓库的代码贡献则遵循仓库根目录的 CONTRIBUTING.md 与 CODE_OF_CONDUCT.md。

总结

围绕 google/ads/googleads/README.md,本仓库提供了 Google Ads API 的完整协议定义与一套实验性的多语言 GAPIC 构建流水线:

  • 协议定义v22v25按版本组织,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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询