关于 api-gateway-openapi-spec-authoring
面向 Google API Gateway 用户的技能,用于编写、迁移和排查 OpenAPI 3.x 配置。它涵盖后端路由、身份验证、配额与部署前验证,并区分 OpenAPI 2.0 和 3.x 扩展的写法。
主要功能
- 01迁移 OpenAPI 2.0 规范
- 02编写 OpenAPI 3.x 配置
- 03配置后端路由与认证
- 04设置指标和配额
- 05验证规范并排查配置错误
适用场景
- 01迁移现有 API 规范
- 02修复 API 配置创建失败
- 03为操作配置认证和配额
- 04部署前验证网关规范
MCP 相关
该技能指出,若要将 API 操作暴露为 MCP 工具,应使用 api-gateway-mcp-server 技能。它本身专注于 OpenAPI 3.x 规范编写及相关配置。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ google/ skills --skill api-gateway-openapi-spec-authoring安装后在 Claude Code 中输入/api-gateway-openapi-spec-authoring确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/api-config-errors.mdattribution.mdopenapi-2-to-3-migration.mdopenapi-3-extensions-and-limits.mdscripts/validate_apigw_openapi.py详细介绍
API Gateway OpenAPI 规范编写
API Gateway 接受 OpenAPI 2.0、3.0.x 和 3.1.x 格式的 API 配置。OpenAPI 3.x 中的 Google 扩展与 OpenAPI 2.0 扩展的结构不同:
- 必需的根级
x-google-api-management块用于命名后端。 x-google-backend是一个字符串,用于引用其中一个后端。- JWT 设置移至
x-google-auth。指标和配额移至x-google-api-management。
使用此技能迁移 OpenAPI 2.0 规范、编写新的 OpenAPI 3.x 规范,或修复创建失败的 API 配置。
归属信息
必须阅读:在执行任何 gcloud、REST API 或 MCP 命令之前,必须阅读 使用归属信息。对于直接在终端中执行的命令(绝不在生成的脚本、Terraform 或用户代码中),在 gcloud 前加上 CLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:api-gateway-openapi-spec-authoring)",并在 User-Agent 标头中追加 agent-skills/1.0 (skill:api-gateway-openapi-spec-authoring)。
前提条件
- 安装工具:
- 安装 Google Cloud CLI。然后使用
gcloud components update更新。**原因:**旧版 CLI 上传 OpenAPI 3.x API 配置时可能会失败。 - 安装 Python 3.10 或更高版本,以及用于验证脚本的 PyYAML。JSON 规范不需要 PyYAML。
pip install "PyYAML>=6.0,<7.0"
- 安装 Google Cloud CLI。然后使用
- 进行身份验证,并选择项目、结算账号和位置:
- 运行
gcloud auth login。 - 使用
gcloud config set project {project_id}选择项目,或使用gcloud projects create {project_id}创建项目。 - 确保
{project_id}已关联有效的结算账号。API Gateway 每月提供一定额度的免费 API 调用,但仍需要有效的结算账号。当前价格请参阅 API Gateway 定价。 - 将
us-central1用作网关命令的默认--location。其他支持的区域请参阅 API Gateway 部署模型。
- 运行
- 启用所需的 Google Cloud API:
gcloud services enable \ apigateway.googleapis.com \ servicemanagement.googleapis.com \ servicecontrol.googleapis.com \ --project={project_id} - 验证 IAM 角色(每个步骤均使用权限范围最小的角色):
- 要创建和更新 API、API 配置及网关:在
{project_id}上授予 API Gateway Admin(roles/apigateway.admin)。 - 要运行
gcloud services enable命令:在{project_id}上授予 Service Usage Admin(roles/serviceusage.serviceUsageAdmin)。 - 要在 API 配置中引用网关服务账号:在
{gateway_sa_email}上授予 Service Account User(roles/iam.serviceAccountUser)。 - 对于需要身份验证的 Cloud Run 后端:在该服务上向
{gateway_sa_email}授予 Cloud Run Invoker 角色(roles/run.invoker)。
- 要创建和更新 API、API 配置及网关:在
决策矩阵
| 任务 | 所需机制 | 关键防护措施 | 详细参考 |
|---|---|---|---|
迁移 OpenAPI 2.0(swagger: "2.0")配置 | 转换标准字段,然后将每个 Google 扩展改为对应的 OpenAPI 3.x 形式。 | Swagger Editor 等转换器会将所有 x-google-* 扩展保留为 OpenAPI 2.0 形式。它还会写入不带 x-google-endpoint 的 servers,导致 API 丢失其基本路径。原因: API Gateway 在 3.x 规范中会拒绝大多数 OpenAPI 2.0 扩展,并返回 The '{extension}' extension is only supported in OpenAPI 2.x。 | OpenAPI 2.0 到 3.x 迁移 |
| 将请求路由到后端 | 根级 x-google-api-management.backends.{backend_name} + 根级或操作级的 x-google-backend: {backend_name} | 为每个后端设置 pathTranslation。原因: 根级 x-google-backend 的默认值是 APPEND_PATH_TO_ADDRESS,而操作级的默认值是 CONSTANT_ADDRESS。CONSTANT_ADDRESS 会将每个请求原样发送到该地址,并将路径参数作为查询参数发送。APPEND_PATH_TO_ADDRESS 会追加完整请求路径及基本路径。切勿在路径项上设置 x-google-backend:API Gateway 会拒绝该配置。 | 扩展和限制 |
| 对调用方进行身份验证 | JWT:使用带有 x-google-auth(issuer、jwksUri、audiences)的 type: oauth2 方案。API 密钥:使用 type: apiKey 方案,并在标头中设置 x-api-key,或在查询中设置 key 或 api_key。 | API Gateway 不会检查 OAuth 作用域。在 security 列表中,要么在每个备选项(OR)中都放入 API 密钥,要么都不放。切勿在同一个要求对象(AND)中放入两个 JWT 方案。原因: API Gateway 会拒绝这些组合。如果用户要求使用其中一种组合(例如将 JWT 或 API 密钥作为备选项),不要将其写入规范。请说明规则,并编写受支持的选项,例如在每个备选项中都放入 API 密钥,或为每种调用方设置单独的路径。 | 扩展和限制 |
| 添加配额 | x-google-api-management.metrics 和 quota.limits + 每个操作上的 x-google-quota: {metric_name: cost} | 切勿依赖根级或路径级的 x-google-quota。原因: 在 OpenAPI 3.x 中,API Gateway 会忽略此处的配置,且不报错。每个设置了配额的操作都必须要求提供 API 密钥,并确保每个 API 配置中的指标名称保持一致。 | 扩展和限制 |
| 设置基本路径和 CORS | 一个带有 x-google-endpoint 的 servers 条目,例如 url: /v1 | API Gateway 会忽略不带 x-google-endpoint 的 servers 条目。allowCors: true 只会将 CORS 请求传递给后端。原因: 网关不会添加 CORS 标头,因此后端必须响应这些请求。 | 扩展和限制 |
修复失败的 api-configs create | 将错误文本与错误表进行匹配,并修复规范。 | 除非错误与 IAM 有关,或其他 api-configs create 操作成功运行,否则请先修复规范再重试。原因: 对于相同的规范,API Gateway 会返回相同的错误。 | API 配置错误 |
| 将操作公开为 MCP 工具 | api-gateway-mcp-server 技能 | MCP 对工具名称、描述和 tools/list 身份验证设定了规则。如果未安装该技能,请使用此技能编写 OpenAPI 3.x 规范,并按照 配置 MCP 指南设置 MCP 扩展。 | - |
执行工作流和验证循环
- 获取当前规范:
- 使用用户仓库中的规范文件。如果没有该文件,则查找网关的有效 API 配置:
gcloud api-gateway gateways describe {gateway_id} --location={region} --project={project_id} --format="value(apiConfig)" - 输出格式为
projects/{project}/locations/global/apis/{api_id}/configs/{config_id}。打印该配置的规范:gcloud api-gateway api-configs describe {config_id} --api={api_id} --project={project_id} --view=FULL \ --format="value(openapiDocuments[0].document.contents)" | tr '_-' '/+' | base64 --decode - gcloud 会以适用于 URL 的 base64 格式打印内容,因此
tr会在base64 --decode之前替换两个字符。如果配置包含多个 OpenAPI 文档,请将[0]改为[1]、[2],依此类推。
- 使用用户仓库中的规范文件。如果没有该文件,则查找网关的有效 API 配置:
- 编写 OpenAPI 3.x 规范:
- 对于 OpenAPI 2.0 规范,请遵循 OpenAPI 2.0 到 3.x 迁移,并将结果与其中的完整转换示例进行比较。
- 对于新规范,请从 扩展和限制中的模板开始。
- 将
openapi设置为 3.0.x 或 3.1.x 版本。示例使用3.0.4。在 OpenAPI 3.1 中,每个 schema 只能指定一个type。原因: API Gateway 会拒绝type: ["string", "null"]这样的类型列表。 - 为每个操作指定唯一的
operationId和一个responses对象,并且只使用本地$ref值。原因: API Gateway 会拒绝缺少operationId或responses的操作、产生相同方法名的两个operationId(例如getItem和get-Item),以及指向 URL 的$ref。
- 对每个编写或修改的规范运行确定性验证循环,然后再作答或创建 API 配置:
python3 scripts/validate_apigw_openapi.py --spec={spec_file}- 脚本路径相对于此技能所在目录。如果你只在回复中提供规范,请先将其写入临时文件,然后在作答前对该文件运行脚本。
- 如果脚本以代码
1退出("status": "FAIL"),请修复{spec_file}中的所有错误,然后再次运行脚本。持续执行,直到脚本以代码0退出("status": "PASS")。 - 如果脚本以代码
2退出,请修复文件路径或 stderr 显示的 YAML/JSON 语法错误,或者安装 PyYAML。 - 阅读所有警告,例如未设置
pathTranslation的后端、未配置 API 密钥的操作上的配额,或allowCors。请修复问题,或告知用户保留该设置的原因。 - 脚本不会检查所有规则。PASS 表示脚本未发现此技能描述的 API Gateway 问题,但不代表它检查了通用 OpenAPI 有效性,例如指向不存在 schema 的
$ref。原因: 只有第 5 步中的api-configs create才能确认 API Gateway 是否接受该规范。不要告诉用户规范会成功部署,仅仅因为脚本通过了验证。
- 向用户概述规范,并在部署前征得批准。 说明以下各项:
- 你迁移或移除的每个 OpenAPI 2.0 扩展,例如 OpenAPI 3.x 不支持的
x-google-allow。还要说明其他所有更改,例如新增的operationId或修正的地址。 - 每个后端的
pathTranslation(脚本输出中的backend_path_translation),以及路径参数现在会作为查询参数发送到后端的每个操作(path_parameters_as_query)。使用APPEND_PATH_TO_ADDRESS时,后端还会收到基础路径。 - 哪些操作需要 JWT 或 API 密钥,哪些后端会收到 ID 令牌以及相应的受众,并说明 API Gateway 不会检查 OAuth 作用域。
- 配额指标和限制,并说明每个指标名称都与当前 API 配置匹配。
- 你迁移或移除的每个 OpenAPI 2.0 扩展,例如 OpenAPI 3.x 不支持的
- 创建新的 API 配置并更新网关(更新生产网关前,请先征得人工批准):
gcloud api-gateway api-configs create {new_config_id} \ --api={api_id} \ --openapi-spec={spec_file} \ --backend-auth-service-account={gateway_sa_email} \ --project={project_id} gcloud api-gateway gateways update {gateway_id} \ --api={api_id} \ --api-config={new_config_id} \ --location={region} \ --project={project_id}- 对于新网关,请使用相同的标志运行
gcloud api-gateway gateways create {gateway_id},而不是gateways update。如果 API 不存在,api-configs create会创建该 API。 - 如果某个操作需要 API 密钥,请启用该 API 的托管服务。使用
gcloud api-gateway apis describe {api_id} --project={project_id} --format="value(managedService)"获取其名称,然后运行gcloud services enable {managed_service} --project={project_id}。还要在创建该 API 密钥的每个项目中启用此服务。 - 每次更改都使用新的配置 ID,因为现有 API 配置的规范无法更改。
- 每个 API 一次只运行一个
api-configs create,并等待其完成。大型 API 配置可能需要最多十分钟才能创建完成。 - 如果
api-configs create失败,请在 API 配置错误中查找错误文本,修复规范,然后返回第 3 步。 - 在新配置开始处理流量前,保留之前的 API 配置。要回滚,请使用之前的配置 ID 运行
gateways update。
- 对于新网关,请使用相同的标志运行
- 验证网关:
- 运行
gcloud api-gateway gateways describe {gateway_id} --location={region} --project={project_id} --format="value(state,defaultHostname)",并等待状态变为ACTIVE。 - 使用操作所需的凭据,向每个已更改路径发送请求,地址为
https://{default_hostname}{base_path}{path}。检查后端收到的路径和参数是否符合预期。 - HTML
404 Page not found表示网关尚未就绪。请检查最近一次创建或更新操作是否已完成;在更改配置前,重试请求。网关更新期间,部分请求仍可能到达之前的 API 配置。JSON 404(The current request is not defined by this API.)表示当前有效的 API 配置未定义该路径。
- 运行
部署前检查清单
-
openapi为3.0.x或3.1.x,且规范中没有 OpenAPI 2.0 扩展,例如安全方案上的x-google-management、x-google-endpoints、x-google-api-name、x-google-allow或x-google-issuer。 -
x-google-api-management.backends定义了所有后端,每个x-google-backend都是一个指向其中某个后端名称的字符串,且没有路径项设置x-google-backend。 - 每个后端都设置了
pathTranslation。 - 每个操作都有唯一的
operationId和responses对象,且每个路径变量都有一个in: path且required: true的参数。 - 每个
x-google-quota都位于需要 API 密钥的操作上,且每个指标名称都与当前 API 配置匹配。 - 最多只有一个
servers条目设置了x-google-endpoint,且其 URL 不包含自定义端口。 -
python3 scripts/validate_apigw_openapi.py --spec={spec_file}返回"status": "PASS"(退出代码为0)。
资源清理
拆除测试环境时,为避免持续产生费用,请先申请人工审批,再按依赖顺序删除资源:
gcloud api-gateway gateways delete {gateway_id} --location={region} --project={project_id}
gcloud api-gateway api-configs delete {config_id} --api={api_id} --project={project_id}
gcloud api-gateway apis delete {api_id} --project={project_id}