gogcligog api describe命令详解:在终端中深入探索 Google Discovery API 与方法的完整指南
【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli
gog api describe是 gogcli(Google Workspace in your terminal)中用于内省 Google Discovery API的核心命令:给定 API 名称与版本号,即可在终端中查看该 API 的完整能力清单(标题、文档链接、全部方法),并可按方法 ID 进一步查看单个方法的参数、HTTP 动词与 OAuth 作用域等元数据。阅读本文后,你将掌握该命令的全部位置参数、输出结构、全局 Flags 的语义,以及其背后的 Discovery 文档获取、24 小时磁盘缓存与服务端回退机制,能够把它与gog api list、gog api call组合成一条"先探索、再调用"的完整工作流。
命令定位:gog api家族中的"内省者"
gog api子命令组在 gogcli 中承担"通用 Google API 访问"职责,其下有三个子命令(定义见 internal/cmd/api.go):
- gog api list——列出 Google Discovery API 目录(默认仅列出 preferred 版本,可用
--all包含非首选版本); gog api describe(本文主角)——描述某个 Discovery API 或其中的单个方法;- gog api call——直接调用某个由 Discovery 描述的方法(以 OAuth 作用域自动选择、路径/查询参数拼接为核心)。
三者共享同一份 Discovery 文档读取与缓存基础设施:describe负责"读懂" API,call负责"使用" API,list负责"发现" API。这与 gogcli 提供的大量一等公民命令(如gog gmail ...、gog drive ...)互为补充——当你需要访问尚未提供专有命令的 Google API 时,gog api家族就是通用逃生通道。
使用语法与位置参数
gog api describe <api> <version> [<method>] [flags]| 位置参数 | 必填 | 含义 |
|---|---|---|
<api> | 是 | Discovery API 名称,例如gmail、drive、calendar |
<version> | 是 | Discovery API 版本,例如v1、v3 |
<method> | 否 | 可选的 Discovery 方法 ID,例如gmail.users.labels.list |
对应源码结构见 internal/cmd/api.go 中APIDescribeCmd的定义:API与Version为必填位置参数,Method标记为optional。命令自身独有的 Flags 只有--no-cache(NoCache bool),其余均为 gogcli 全局 Flags。
不带<method>:查看整个 API 的摘要
省略方法 ID 时,命令返回一个 JSON 对象,包含四个字段(见 internal/cmd/api.go):
name——API 名称;version——API 版本;title——API 的展示标题;documentation_link——Google 官方文档链接;methods——按方法 ID 排序后的全部方法列表。
例如:
gog api describe gmail v1输出结构示意:
{ "name": "gmail", "version": "v1", "title": "Gmail API", "documentation_link": "https://developers.google.com/gmail/api", "methods": [ { "id": "gmail.users.drafts.create", "resource": "users.drafts", "name": "create", "spec": { "httpMethod": "POST", "path": "gmail/v1/users/{userId}/drafts", ... } } ] }这里的methods数组由discoveryapi.Methods()生成(internal/discoveryapi/discovery.go):它把 Discovery 文档中顶层methods与嵌套resources中的方法递归拍平,为每个方法补齐id(若缺失则用resource.name拼接),最后按 ID 字典序排序,保证输出稳定、便于脚本 diff。
带<method>:查看单个方法的完整规格
传入方法 ID 后,命令通过discoveryapi.FindMethod()(internal/discoveryapi/discovery.go)精确匹配方法,并直接输出该方法的 JSON 规格(Method结构,见 internal/discoveryapi/discovery.go):
gog api describe gmail v1 gmail.users.labels.list{ "id": "gmail.users.labels.list", "resource": "users.labels", "name": "list", "spec": { "id": "gmail.users.labels.list", "httpMethod": "GET", "path": "gmail/v1/users/{userId}/labels", "parameters": { "userId": { "location": "path", "required": true, "type": "string" }, "maxResults": { "location": "query", "type": "integer", "default": "100" } }, "scopes": ["https://www.googleapis.com/auth/gmail.readonly"] } }FindMethod同时接受完整 ID(如gmail.users.labels.list)或resource.name形式(如users.labels.list),匹配到即返回;找不到时返回discovery method not found错误。方法未命中时,APIDescribeCmd.Run会将其包装为 usage 错误返回(internal/cmd/api.go)。
这些字段正是gog api call组装真实 HTTP 请求所需的全部信息:httpMethod决定请求动词,path中的{param}与+param占位符由路径参数填充,parameters决定必填校验与查询串构造,scopes用于选择 OAuth 作用域(详见 internal/discoveryapi/discovery.go 的BuildURL)。因此,describe输出的方法规格本质上就是call的可执行蓝图。
Flags 全表
与 gogcli 其他命令一致,gog api describe继承了完整的全局 Flags 体系。以下为命令文档(docs/commands/gog-api-describe.md)中登记的全部 Flags:
| Flag | 类型 | 默认值 | 说明 |
|---|---|---|---|
--access-token | string | 直接使用提供的访问令牌(绕过存储的 refresh token;令牌约 1 小时后过期) | |
-a--account--acct | string | 用于已认证 Google API 命令的账号邮箱、别名或 auto | |
--client | string | OAuth 客户端名称(选择已存凭据与令牌桶) | |
--color | string | auto | 颜色输出:auto|always|never |
--disable-commands | string | 禁用的命令列表(逗号分隔;支持点路径) | |
-n--dry-run--dryrun--noop--preview | bool | 不做出更改;打印预期操作并以成功退出 | |
--enable-commands | string | 启用的命令前缀列表(逗号分隔;支持点路径;限制 CLI) | |
--enable-commands-exact | string | 精确启用的命令列表(逗号分隔;支持点路径;父命令不会启用子命令) | |
-y--force--assume-yes--yes | bool | 跳过破坏性命令的确认 | |
--gmail-no-send | bool | false | 阻止 Gmail 发送操作(Agent 安全) |
-h--help | kong.helpFlag | 显示上下文相关帮助 | |
--home | string | 覆盖 gogcli 配置/数据/状态/缓存根目录(等价于 GOG_HOME) | |
-j--json--machine | bool | false | 向 stdout 输出 JSON(最适合脚本化) |
--no-cache | bool | 获取 Discovery 文档时不读写 24 小时磁盘缓存 | |
--no-input--non-interactive--noninteractive | bool | 永不提示;失败即退出(适合 CI) | |
-p--plain--tsv | bool | false | 向 stdout 输出稳定、可解析的纯文本(TSV;无颜色) |
--quota-project | string | 用于结算 API 用量的 Google Cloud 项目(以 X-Goog-User-Project 发送;某些 API 在 --access-token 或 ADC 下需要它) | |
--readonly | bool | false | 在运行时阻止修改型 API 请求;auth add 也会请求只读 OAuth 作用域 |
--results-only | bool | JSON 模式下仅输出主要结果(丢弃 nextPageToken 等信封字段) | |
--select--pick--project | string | JSON 模式下选择逗号分隔的字段(尽力而为;支持点路径)。多数命令推荐使用 --fields | |
-v--verbose | bool | 启用详细日志 | |
--version | kong.VersionFlag | 打印版本并退出 | |
--wrap-untrusted | bool | false | JSON/raw 输出中,为抓取到的文本字段包裹外部不可信内容标记 |
Flags 解读要点
--no-cache是本命令的关键开关:它绕过 Discovery 文档的 24 小时磁盘缓存,强制向远程获取最新文档。调试"为什么 describe 出的方法与线上不一致"时优先检查它。其余全局 Flags 由 gogcli 根命令注入(RootFlags),例如命令启用/禁用策略(--enable-commands/--disable-commands)在 internal/cmd/api.go 的enforceDiscoveryMethodPolicy中还会以api.<method-id>点路径形式对gog api call生效,保证通用调用也受 CLI 白名单约束。--json/--plain双输出模式:虽然describe本身即输出 JSON,全局--json(等价于--machine)与--plain(TSV)为脚本化消费提供了稳定、无装饰的输出通道;--select支持点路径字段裁剪,适合只取methods子集。--wrap-untrusted与--readonly是面向 Agent/LLM 场景的安全 Flags:前者在 JSON/raw 输出中为远端返回的文本字段包裹不可信内容标记(见 internal/cmd/api_test.go 对EXTERNAL_UNTRUSTED_CONTENT标记的测试),后者从运行时层面拦截修改型请求。
执行流程与源码走读
APIDescribeCmd.Run的执行链路(internal/cmd/api.go)只有三步,简洁而清晰:
- 获取 Discovery 文档:调用
discoveryDescriptionClient(ctx, c.NoCache).Description(ctx, c.API, c.Version)。discoveryDescriptionClient(internal/cmd/api.go)在未指定--no-cache时,会把缓存目录指向commandLayout中的cache/discovery子目录,并挂载到 Discovery 客户端上。 - 输出 API 摘要或查找方法:若未提供
<method>,直接输出包含methods的摘要 JSON;否则调用FindMethod精确匹配。 - 写出结果:统一经
outfmt.WriteJSON写至 stdout。
Client.Description(internal/discoveryapi/discovery.go)是核心实现,其行为包括:
- 校验
api、version非空,否则返回ErrInvalidDescription; - 构造请求 URL
{base}/apis/{api}/{version}/rest(默认 base 为https://www.googleapis.com/discovery/v1,可用环境变量GOG_DISCOVERY_BASE_URL覆盖,便于测试与代理场景); - 启用缓存时先尝试读缓存,命中则直接返回,避免网络往返;
- 响应体以
16<<20(16 MiB)为上限流式读取,超限或非 2xx 均返回错误; - 成功后异步写入缓存(若上下文尚未取消)。
Discovery 文档的 24 小时磁盘缓存
--no-cache的"反义词"——默认行为——由 internal/discoveryapi/cache.go 实现,缓存策略相当工程化:
- TTL:
descriptionCacheTTL = 24 * time.Hour,文件修改时间超过一天即视为失效; - 键:对请求 URL 做 SHA-256,文件名形如
<sha256>.json,并通过descriptionCacheKey区分默认 base URL(额外拼接service-hosted-fallback哨兵,避免显式 base URL 复用服务端回退结果); - 容量:最多
32个条目、总大小上限64 MiB、单条目上限16 MiB,写入前会先清理过期/超限条目(LRU 风格按 ModTime 排序淘汰); - 并发:跨进程写入用
filelock.Shared的排他锁串行化,锁等待上限 100ms,锁竞争或文件系统错误一律当作缓存未命中处理(绝不阻塞网络路径); - 原子性:先写
.discovery-*临时文件,再os.Rename落位。
缓存命中与否有直接测试保障:TestDiscoveryCommandCacheAndBypass(internal/cmd/api_test.go)验证了"两次 describe 只发一次网络请求""describe 与 call 共享同一份缓存""--no-cache强制重新拉取"三个行为。
服务端回退(Service-Hosted Discovery)
当默认 Discovery 端点返回 404 且使用默认 base URL 时,客户端会回退到服务自身托管的 Discovery 文档:https://{service}.googleapis.com/$discovery/rest?version={version}(internal/discoveryapi/discovery.go)。回退前的服务名会经过严格的合法性校验(小写字母/数字/连字符、长度不超过 63、不以连字符开头结尾),防止拼凑出恶意主机名。测试 internal/discoveryapi/discovery_test.go 演示了meet v2的完整回退链路,并断言"自定义 base URL 不触发回退""非 404 错误不触发回退"等边界。
典型使用场景
场景一:先 list 发现,再 describe 深入
# 查看 Discovery API 目录(只看 preferred 版本) gog api list # 深入某个 API:拿到全部方法清单 gog api describe drive v3 # 精确定位单个方法的规格 gog api describe drive v3 drive.files.list场景二:为gog api call做准备
# 确认方法名、参数与作用域 gog api describe calendar v3 calendar.events.list --json --select spec.parameters # 直接把 describe 得到的方法规格作为 call 的参数依据 gog api call calendar v3 calendar.events.list --params '{"calendarId":"primary","maxResults":10}'注意:gog api call对非只读方法要求显式--allow-write,且受命令策略(--enable-commands/--disable-commands)、--readonly、Gmail no-send 等安全机制约束(见 internal/cmd/api.go),describe阶段先看清方法的httpMethod与scopes,是规避误写操作的有效前置步骤。
场景三:脚本与 Agent 场景
# 机器可读输出,配合 jq 提取方法 ID 列表 gog api describe gmail v1 --json | jq -r '.methods[].id' # CI 中无需交互,且绕过缓存获取最新文档 gog api describe gmail v1 --no-cache --no-input --jsondescribe是纯只读命令(仅 GET Discovery 文档),配合--no-input可安全地用于 CI 与自动化流水线;--wrap-untrusted则适合 LLM Agent 消费输出时区分"可信 CLI 元数据"与"远端返回内容"。
常见问题与使用建议
- 输出"太大"怎么办?不带
<method>时methods数组可能很长,优先用--select(或--json+ 外部jq)裁剪字段,或直接指定<method>只看单个方法。 - 想要最新文档?使用
--no-cache;注意它同时跳过缓存写入,频繁使用会失去缓存加速(单次请求受 30s HTTP 超时与 16 MiB 响应上限约束,见 internal/discoveryapi/discovery.go)。 - 方法找不到?先确认版本号正确(可用
gog api list --all核对),再确认方法 ID 形式为resource.name或完整id;FindMethod对两者均支持。 - 文档页从哪来?docs/commands/gog-api-describe.md 页首注明该页由
gog schema --json生成,不应手工编辑,而是通过make docs-commands重新生成——这意味着本文中的 Flags 表与命令帮助文本始终与源码定义保持同步。
总而言之,gog api describe是 gogcli 中把"Google 的 Discovery 元数据"翻译成"可读、可脚本化、可执行"的枢纽命令:向上承接gog api list的目录发现,向下为gog api call提供精确的方法蓝图,同时通过 24 小时缓存、服务端回退与全局安全 Flags,把通用 API 访问的探索体验做得既快又稳。
【免费下载链接】gogcliGoogle Workspace in your terminal.项目地址: https://gitcode.com/GitHub_Trending/gogcl/gogcli
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考