api-gateway-openapi-spec-authoring
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAPI Gateway OpenAPI Spec Authoring
API Gateway OpenAPI 规范编写
API Gateway accepts API configs in OpenAPI 2.0, 3.0.x, and 3.1.x. The Google extensions in OpenAPI 3.x have a different structure from the OpenAPI 2.0 extensions:
- A required root block names the backends.
x-google-api-management - is a string that references one of these backends.
x-google-backend - The JWT settings move into . The metrics and quotas move into
x-google-auth.x-google-api-management
Use this skill to migrate an OpenAPI 2.0 spec, write a new OpenAPI 3.x spec, or fix an API config that fails to create.
API Gateway 接受 OpenAPI 2.0、3.0.x 和 3.1.x 格式的 API 配置。OpenAPI 3.x 中的 Google extension 与 OpenAPI 2.0 extension 的结构不同:
- 根级别必须包含 块,用于命名 backends。
x-google-api-management - 是一个字符串,用于引用其中某个 backend。
x-google-backend - JWT 设置迁移到 。指标和配额迁移到
x-google-auth。x-google-api-management
使用此 skill 可迁移 OpenAPI 2.0 规范、编写新的 OpenAPI 3.x 规范,或修复无法创建的 API 配置。
Attribution
使用归属说明
MUST READ: Before executing any , REST API, or MCP command, you
MUST read Usage Attribution. For commands executed
directly in the terminal (never in generated scripts, Terraform, or user code),
prefix with
and append to headers.
gcloudgcloudCLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:api-gateway-openapi-spec-authoring)"agent-skills/1.0 (skill:api-gateway-openapi-spec-authoring)User-Agent必须阅读:在执行任何 、REST API 或 MCP 命令之前,你必须阅读 使用归属说明。对于直接在终端中执行的命令(绝不包括生成的脚本、Terraform 或用户代码),请在 前添加
,并向 headers 中追加 。
gcloudgcloudCLOUDSDK_METRICS_REQUEST_ATTRIBUTION="agent-skills/1.0 (skill:api-gateway-openapi-spec-authoring)"User-Agentagent-skills/1.0 (skill:api-gateway-openapi-spec-authoring)Prerequisites
前置条件
- Install the tools:
- Install the Google Cloud CLI. Then update it with . Rationale: an old CLI can fail when it uploads an OpenAPI 3.x API config.
gcloud components update - Install Python 3.10 or later and PyYAML for the validator script. A JSON spec does not need PyYAML.
bash
pip install "PyYAML>=6.0,<7.0"
- Install the Google Cloud CLI. Then update it with
- Authenticate, and select the project, billing, and location:
- Run .
gcloud auth login - Select a project with , or create one with
gcloud config set project {project_id}.gcloud projects create {project_id} - Make sure that an active billing account is linked to . API Gateway has a free monthly allowance of API calls, but it still needs an active billing account. For current prices, see API Gateway pricing.
{project_id} - Use as the default
us-central1for gateway commands. For the other supported regions, see API Gateway deployment model.--location
- Run
- Enable the required Google Cloud APIs:
bash
gcloud services enable \ apigateway.googleapis.com \ servicemanagement.googleapis.com \ servicecontrol.googleapis.com \ --project={project_id} - Verify the IAM roles (use the most restrictive role for each step):
- To create and update the API, API configs, and gateways: API Gateway Admin () on
roles/apigateway.admin.{project_id} - To run the commands: Service Usage Admin (
gcloud services enable) onroles/serviceusage.serviceUsageAdmin.{project_id} - To reference the gateway service account in an API config: Service Account User () on
roles/iam.serviceAccountUser.{gateway_sa_email} - For a Cloud Run backend that requires authentication: grant the Cloud Run Invoker role (
{gateway_sa_email}) on the service.roles/run.invoker
- To create and update the API, API configs, and gateways: API Gateway Admin (
- 安装工具:
- 安装 Google Cloud CLI,然后使用 更新它。原因: 旧版 CLI 在上传 OpenAPI 3.x API 配置时可能会失败。
gcloud components update - 安装 Python 3.10 或更高版本,以及校验脚本所需的 PyYAML。JSON 规范不需要 PyYAML。
bash
pip install "PyYAML>=6.0,<7.0"
- 安装 Google Cloud CLI,然后使用
- 进行身份验证,并选择项目、结算账号和位置:
- 运行 。
gcloud auth login - 使用 选择项目,或使用
gcloud config set project {project_id}创建项目。gcloud projects create {project_id} - 确保 已关联有效的结算账号。API Gateway 每月提供免费的 API 调用额度,但仍需要有效的结算账号。有关当前价格,请参阅 API Gateway 定价。
{project_id} - 对 gateway 命令,默认使用 作为
us-central1。有关其他支持的区域,请参阅 API Gateway 部署模型。--location
- 运行
- 启用所需的 Google Cloud API:
bash
gcloud services enable \ apigateway.googleapis.com \ servicemanagement.googleapis.com \ servicecontrol.googleapis.com \ --project={project_id} - 验证 IAM roles(每个步骤均使用权限最少的 role):
- 要创建和更新 API、API configs 及 gateways:在 上使用 API Gateway Admin (
{project_id})。roles/apigateway.admin - 要运行 命令:在
gcloud services enable上使用 Service Usage Admin ({project_id})。roles/serviceusage.serviceUsageAdmin - 要在 API 配置中引用 gateway service account:在 上使用 Service Account User (
{gateway_sa_email})。roles/iam.serviceAccountUser - 对于需要身份验证的 Cloud Run backend:在该 service 上向 授予 Cloud Run Invoker role (
{gateway_sa_email})。roles/run.invoker
- 要创建和更新 API、API configs 及 gateways:在
Decision Matrix
决策矩阵
| Task | Required Mechanism | Critical Guardrail | Detailed Reference |
|---|---|---|---|
Migrate an OpenAPI 2.0 ( | Convert the standard fields, then move each Google extension to its OpenAPI 3.x form. | A converter such as Swagger Editor leaves every | OpenAPI 2.0 to 3.x Migration |
| Route requests to backends | Root | Set | Extensions and Limits |
| Authenticate callers | JWT: | API Gateway does not check OAuth scopes. In a | Extensions and Limits |
| Add quotas | | NEVER rely on | Extensions and Limits |
| Set the base path and CORS | One | API Gateway ignores | Extensions and Limits |
Fix a failed | Match the error text to the error table, and fix the spec. | Fix the spec before you retry, unless the error is about IAM or another | API Config Errors |
| Expose operations as MCP tools | The | MCP adds rules for tool names, descriptions, and | - |
| 任务 | 所需机制 | 关键注意事项 | 详细参考 |
|---|---|---|---|
迁移 OpenAPI 2.0 ( | 转换标准字段,然后将每个 Google extension 转换为对应的 OpenAPI 3.x 形式。 | Swagger Editor 等 converter 会将所有 | OpenAPI 2.0 到 3.x 迁移 |
| 将请求路由到 backends | 根级别的 | 每个 backend 都必须设置 | Extensions 与限制 |
| 对调用方进行身份验证 | JWT:使用 | API Gateway 不检查 OAuth scopes。在 | Extensions 与限制 |
| 添加配额 | | 绝不要依赖根级别或 path 级别的 | Extensions 与限制 |
| 设置 base path 和 CORS | 使用一个包含 | API Gateway 会忽略不含 | Extensions 与限制 |
修复失败的 | 将错误文本与错误表进行匹配,然后修复规范。 | 除非错误涉及 IAM 或另一个正在运行的 | API 配置错误 |
| 将 operations 暴露为 MCP tools | | MCP 对 tool names、descriptions 和 | - |
Execution Workflow and Validation Loop
执行工作流与验证循环
- Get the current spec:
- Use the spec file in the user's repository. If there is no file, find the active API config of the gateway:
bash
gcloud api-gateway gateways describe {gateway_id} --location={region} --project={project_id} --format="value(apiConfig)" - The output is . Print the spec of that config:
projects/{project}/locations/global/apis/{api_id}/configs/{config_id}bashgcloud 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 prints the contents in URL-safe base64, so changes two characters before
tr. If the config has more than one OpenAPI document, changebase64 --decodeto[0],[1], and so on.[2]
- Use the spec file in the user's repository. If there is no file, find the active API config of the gateway:
- Write the OpenAPI 3.x spec:
- For an OpenAPI 2.0 spec, follow OpenAPI 2.0 to 3.x Migration, and compare your result with its complete converted example.
- For a new spec, start from the template in Extensions and Limits.
- Set to a 3.0.x or 3.1.x version. The examples use
openapi. In OpenAPI 3.1, give each schema one3.0.4. Rationale: API Gateway rejects a type list such astype.type: ["string", "null"] - Give every operation a unique and a
operationIdobject, and use only localresponsesvalues. Rationale: API Gateway rejects an operation without$reforoperationId, tworesponsesvalues that give the same method name, such asoperationIdandgetItem, and aget-Itemto a URL.$ref
- Run the deterministic validation loop on every spec that you write or change, before you answer or create the API config:
bash
python3 scripts/validate_apigw_openapi.py --spec={spec_file}- The script path is relative to the directory of this skill. If you only return the spec in your reply, write it to a temporary file, and run the script on that file before you answer.
- If the script exits with code (
1), fix every error in"status": "FAIL", and run the script again. Continue until it exits with code{spec_file}(0)."status": "PASS" - If the script exits with code , fix the file path or the YAML/JSON syntax error that stderr shows, or install PyYAML.
2 - Read every warning, such as a backend without , a quota on an operation without an API key, or
pathTranslation. Fix it, or tell the user why you keep it.allowCors - The script does not check every rule. A PASS means that it found none of the API Gateway problems that this skill describes. It does not check general OpenAPI validity, such as a to a schema that does not exist. Rationale: only
$refin step 5 shows that API Gateway accepts the spec. Do not tell the user that the spec deploys because the script passed.api-configs create
- Summarize the spec for the user, and get approval before you deploy. State each of these points:
- Each OpenAPI 2.0 extension that you moved or removed, such as , which OpenAPI 3.x does not support. Also state each other change, such as an added
x-google-allowor a fixed address.operationId - The of each backend (
pathTranslationin the script output), and each operation whose path parameters now go to the backend as query parameters (backend_path_translation). Withpath_parameters_as_query, the backend also receives the base path.APPEND_PATH_TO_ADDRESS - Which operations need a JWT or an API key, which backends receive an ID token and with which audience, and that API Gateway does not check OAuth scopes.
- The quota metrics and limits, and that each metric name matches the current API config.
- Each OpenAPI 2.0 extension that you moved or removed, such as
- Create a new API config and update the gateway (request human approval before you update a production gateway):
bash
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}- For a new gateway, run with the same flags instead of
gcloud api-gateway gateways create {gateway_id}.gateways updatecreates the API if it does not exist.api-configs create - If an operation requires an API key, enable the managed service of the API. Get its name with , and then run
gcloud api-gateway apis describe {api_id} --project={project_id} --format="value(managedService)". Also enable it in each project that creates API keys for the API.gcloud services enable {managed_service} --project={project_id} - Use a new config ID for each change, because you cannot change the spec of an existing API config.
- Run one at a time for each API, and wait for it to finish. A large API config can take up to ten minutes to create.
api-configs create - If fails, find the error text in API Config Errors, fix the spec, and go back to step 3.
api-configs create - Keep the previous API config until the new one serves traffic. To roll back, run with the previous config ID.
gateways update
- For a new gateway, run
- Verify the gateway:
- Run , and wait until the state is
gcloud api-gateway gateways describe {gateway_id} --location={region} --project={project_id} --format="value(state,defaultHostname)".ACTIVE - Send a request to each changed path at , with the credential that the operation requires. Check that the backend receives the path and parameters that you expect.
https://{default_hostname}{base_path}{path} - An HTML means that the gateway is not ready. Check that the last create or update finished, and retry before you change the config. During a gateway update, some requests can still reach the previous API config. A JSON 404 (
404 Page not found) means that the active API config does not define the path.The current request is not defined by this API.
- Run
- 获取当前规范:
- 使用用户 repository 中的规范文件。如果没有文件,则查找 gateway 当前使用的 API 配置:
bash
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}bashgcloud 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-safe base64 格式打印内容,因此需要先通过 更改两个字符,再执行
tr。如果配置包含多个 OpenAPI documents,请将base64 --decode改为[0]、[1]等。[2]
- 使用用户 repository 中的规范文件。如果没有文件,则查找 gateway 当前使用的 API 配置:
- 编写 OpenAPI 3.x 规范:
- 对于 OpenAPI 2.0 规范,请遵循 OpenAPI 2.0 到 3.x 迁移,并将结果与其中完整的转换示例进行比较。
- 对于新规范,请从 Extensions 与限制 中的模板开始。
- 将 设置为 3.0.x 或 3.1.x 版本。示例使用
openapi。在 OpenAPI 3.1 中,每个 schema 只能设置一个3.0.4。原因: API Gateway 会拒绝类似type的 type list。type: ["string", "null"] - 为每个 operation 设置唯一的 和
operationIdobject,并且只能使用本地responses值。原因: API Gateway 会拒绝缺少$ref或operationId的 operation、生成相同方法名的两个responses值(例如operationId和getItem),以及指向 URL 的get-Item。$ref
- 对于编写或修改的每个规范,在回复用户或创建 API 配置之前,运行确定性验证循环:
bash
python3 scripts/validate_apigw_openapi.py --spec={spec_file}- 脚本路径相对于此 skill 所在的目录。如果仅在回复中返回规范,请先将其写入临时文件,并在回复前对该文件运行脚本。
- 如果脚本以代码 退出(
1),请修复"status": "FAIL"中的所有错误,然后再次运行脚本。持续执行,直到脚本以代码{spec_file}退出(0)。"status": "PASS" - 如果脚本以代码 退出,请修复文件路径或 stderr 中显示的 YAML/JSON 语法错误,或者安装 PyYAML。
2 - 阅读每条 warning,例如 backend 缺少 、operation 在没有 API key 的情况下设置配额,或者出现
pathTranslation。修复这些问题,或者告知用户保留它们的原因。allowCors - 该脚本不会检查所有规则。PASS 表示脚本没有发现此 skill 所描述的任何 API Gateway 问题,但它不会检查一般性的 OpenAPI 有效性,例如 指向不存在的 schema。原因: 只有第 5 步中的
$ref才能证明 API Gateway 接受该规范。不要因为脚本通过就告诉用户规范可以部署。api-configs create
- 向用户概述规范,并在部署前获得批准。 说明以下各点:
- 移动或删除了哪些 OpenAPI 2.0 extensions,例如 OpenAPI 3.x 不支持的 。同时说明其他每项更改,例如新增
x-google-allow或修复后的地址。operationId - 每个 backend 的 (脚本输出中的
pathTranslation),以及哪些 operations 的 path parameters 现在会作为 query parameters 发送给 backend(backend_path_translation)。使用path_parameters_as_query时,backend 还会收到 base path。APPEND_PATH_TO_ADDRESS - 哪些 operations 需要 JWT 或 API key,哪些 backends 会收到 ID token 及其 audience,并说明 API Gateway 不检查 OAuth scopes。
- 配额 metrics 和 limits,并说明每个 metric name 都与当前 API 配置一致。
- 移动或删除了哪些 OpenAPI 2.0 extensions,例如 OpenAPI 3.x 不支持的
- 创建新的 API 配置并更新 gateway(更新生产 gateway 前需获得人工批准):
bash
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}- 对于新 gateway,请使用相同的 flags 运行 ,而不是
gcloud api-gateway gateways create {gateway_id}。如果 API 不存在,gateways update会创建它。api-configs create - 如果某个 operation 需要 API key,请启用该 API 的 managed service。使用 获取其名称,然后运行
gcloud api-gateway apis describe {api_id} --project={project_id} --format="value(managedService)"。还应在每个为该 API 创建 API keys 的项目中启用它。gcloud services enable {managed_service} --project={project_id} - 每次更改都应使用新的 config ID,因为无法修改现有 API 配置的规范。
- 每个 API 每次只运行一个 ,并等待其完成。大型 API 配置的创建时间最长可能达到十分钟。
api-configs create - 如果 失败,请在 API 配置错误 中查找错误文本,修复规范,然后返回第 3 步。
api-configs create - 在新配置开始处理流量之前保留之前的 API 配置。要回滚,请使用之前的 config ID 运行 。
gateways update
- 对于新 gateway,请使用相同的 flags 运行
- 验证 gateway:
- 运行 ,并等待状态变为
gcloud api-gateway gateways describe {gateway_id} --location={region} --project={project_id} --format="value(state,defaultHostname)"。ACTIVE - 使用 operation 所要求的凭据,向 中的每个已修改 path 发送请求。检查 backend 是否收到预期的 path 和 parameters。
https://{default_hostname}{base_path}{path} - HTML 表示 gateway 尚未就绪。检查最后一次 create 或 update 是否已完成,并在修改配置前重试。更新 gateway 期间,部分请求仍可能到达之前的 API 配置。JSON 404(
404 Page not found)表示当前生效的 API 配置未定义该 path。The current request is not defined by this API.
- 运行
Pre-Deployment Checklist
部署前检查清单
- is
openapior3.0.x, and the spec has no OpenAPI 2.0 extension, such as3.1.x,x-google-management,x-google-endpoints,x-google-api-name, orx-google-allowon a security scheme.x-google-issuer - defines every backend, every
x-google-api-management.backendsis a string that names one, and no path item setsx-google-backend.x-google-backend - Every backend sets .
pathTranslation - Every operation has a unique and a
operationIdobject, and each path variable has a parameter withresponsesandin: path.required: true - Every is on an operation that requires an API key, and every metric name matches the current API config.
x-google-quota - At most one entry has
servers, and its URL has no custom port.x-google-endpoint - returns
python3 scripts/validate_apigw_openapi.py --spec={spec_file}(exit code"status": "PASS").0
- 为
openapi或3.0.x,且规范中不存在 OpenAPI 2.0 extension,例如 security scheme 上的3.1.x、x-google-management、x-google-endpoints、x-google-api-name或x-google-allow。x-google-issuer - 定义了每个 backend,每个
x-google-api-management.backends都是引用其中某个 backend 的字符串,并且没有 path item 设置x-google-backend。x-google-backend - 每个 backend 都设置了 。
pathTranslation - 每个 operation 都有唯一的 和
operationIdobject,并且每个 path variable 都有一个responses且in: path的 parameter。required: true - 每个 都位于要求 API key 的 operation 上,并且每个 metric name 都与当前 API 配置一致。
x-google-quota - 最多只有一个 entry 包含
servers,并且其 URL 没有自定义端口。x-google-endpoint - 返回
python3 scripts/validate_apigw_openapi.py --spec={spec_file}(退出代码为"status": "PASS")。0
Resource Cleanup
资源清理
To avoid ongoing charges when you tear down a test environment, request human approval, and delete the resources in dependency order:
bash
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}为避免拆除测试环境后继续产生费用,请先获得人工批准,然后按依赖顺序删除资源:
bash
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}