关于 apollo-router
apollo-router 是面向 Apollo Router 使用者的配置生成技能,可按目标版本和环境组装 Router 配置。它强调版本兼容性检查、安全相关参数收集及生成后的验证。
主要功能
- 01按 Router 版本选择模板
- 02区分生产与开发配置
- 03收集并配置可选功能
- 04生成后执行验证清单
- 05提供配置即代码指导
适用场景
- 01为新部署生成生产配置
- 02为开发环境生成 Router 配置
- 03配置身份验证、遥测或流量限制
- 04检查 router.yaml 的版本兼容性
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ apollographql/ skills --skill apollo-router安装后在 Claude Code 中输入/apollo-router确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
divergence-map.mdreferences/configuration.mdconnectors.mdheaders.mdplugins.mdresponse-caching.mdtelemetry.mdtroubleshooting.mdtemplates/v1/development.yamlproduction.yamltemplates/v1/sections/auth.yamlcors.yamlheaders.yamllimits.yamltelemetry.yamltraffic-shaping.yamltemplates/v2/development.yamlproduction.yamltemplates/v2/sections/auth.yamlconnectors.yamlcors.yamlheaders.yamllimits.yamlresponse-caching.yamltelemetry.yamltraffic-shaping.yamlvalidation/checklist.md详细介绍
Apollo Router 配置生成器
Apollo Router 是一个用 Rust 编写的高性能图路由器,用于运行 Apollo Federation 2 超图。它位于子图前端,负责查询规划、执行和响应组合。
此技能会生成与版本匹配的配置。 Router v1 和 v2 在若干关键部分(CORS、JWT 身份验证、连接器)的配置架构不兼容。生成任何配置前,务必先确定目标版本。
第 1 步:选择版本
生成任何配置之前,先询问用户:
Which Apollo Router version are you targeting?
[1] Router v2.x (recommended — current LTS, required for Connectors)
[2] Router v1.x (legacy — end-of-support announced, security patches only)
[3] Not sure — help me decide
如果用户选择 [3],显示:
Quick guide:
• Pick v2 if: you're starting fresh, using Apollo Connectors for REST APIs,
or want backpressure-based overload protection.
• Pick v1 if: you have an existing deployment and haven't migrated yet.
Note: Apollo ended active support for v1.x. The v2.10 LTS (Dec 2025)
is the current baseline. Migration is strongly recommended.
Tip: If you have an existing router.yaml, you can auto-migrate it:
router config upgrade router.yaml
将所选版本保存为 ROUTER_VERSION=v1|v2,用于控制后续所有模板的生成。
第 2 步:选择环境
询问:生产环境还是开发环境?
- 生产环境:强化安全性的默认设置(关闭 introspection、sandbox 和 homepage,隐藏子图错误,要求身份验证,启用健康检查)
- 开发环境:开放的默认设置(启用 introspection 和 sandbox,公开错误,使用文本日志)
从以下路径加载相应的基础模板:
templates/{version}/production.yamltemplates/{version}/development.yaml
第 3 步:选择功能
询问要包含哪些功能:
- JWT 身份验证
- 声明式授权(字段级
@authenticated/@requiresScopes/@policy指令 — 需要 GraphOS + 请求声明) - CORS(浏览器客户端几乎总是需要)
- 操作限制
- 流量整形 / 速率限制
- 遥测(Prometheus、OTLP 跟踪、JSON 日志)
- APQ(自动持久化查询 — 仅用于性能/带宽优化,不是安全控制)
- 持久化查询安全列表(GraphOS PQL 操作允许列表 — 属于安全控制;与 APQ 不同)
- 连接器(REST API 集成 — 仅限 Router v2;GA 键为
connectors,早期 v2 预览版键为preview_connectors) - 订阅
- 请求头传播
- 响应缓存(使用 Redis 缓存实体和根字段 — 仅限 Router v2,v2.6.0+)
第 4 步:收集参数
针对每个选定的功能,收集所需的值。
- 对于
auth、cors、headers、limits、telemetry和traffic-shaping,使用templates/{version}/sections/中的章节模板。 - 对于 v2 中的连接器,以
templates/v2/sections/connectors.yaml为源。 - 对于 APQ 和订阅,从所选的基础模板(
templates/{version}/production.yaml或templates/{version}/development.yaml)或参考资料中复制代码片段。 - 仅当
ROUTER_VERSION=v2时才提供连接器。
CORS
- 允许的来源列表(生产环境中切勿使用
"*")
JWT 身份验证
- JWKS URL
- 颁发者 — 注意:v1 使用单数形式的
issuer,v2 使用复数形式的issuers数组
声明式授权(字段级)
通过应用于子图架构的
@authenticated、@requiresScopes和@policy指令,在路由器中强制执行字段级和类型级访问控制。这一层可以表达全局authorization.require_authentication门控无法表达的规则。这是 GraphOS 功能(Enterprise;Developer/Standard 计划需要 Router v2.6.0+),并且要求路由器连接到 GraphOS。指令默认已启用——配置只能将其关闭。
推荐使用这些指令前,请确认先决条件:
- 路由器已连接到 GraphOS(Router v1.29.1+;Developer/Standard 计划需要 v2.6.0+)。
- 有声明来源。 指令会在
apollo::authentication::jwt_claims上下文键中评估声明。可通过 JWT 身份验证(也要配置此功能)或注入声明的协处理器来填充。 @policy还需要 Supergraph 插件(Rhai 脚本或协处理器)来评估每项策略——路由器会将所需策略提取到apollo::authorization::required_policies,但不会自行判定策略。
请询问:
- 哪些字段/类型需要保护,保护级别是什么?(
@authenticated= 任何有效身份;@requiresScopes= 特定作用域;@policy= 自定义逻辑。) - 作用域/声明来自哪里?(JWT 声明,还是由协处理器注入。)
这些指令位于子图架构中,而不是 router.yaml 中。路由器配置只能启用/禁用该功能,并为 @policy 接入评估插件。请参阅 references/configuration.md → 授权。
持久化查询安全名单(GraphOS PQL)
这与 APQ 不同。 APQ(
apq)是一种运行时带宽优化机制,会缓存客户端发送的任何操作——它不提供任何安全保护。安全名单使用由 GraphOS 管理的持久化查询列表(PQL),客户端在构建时注册查询;路由器随后会拒绝列表之外的操作。这就是“持久化查询安全名单”安全控制。这是 GraphOS 功能,要求路由器连接到 GraphOS(APOLLO_KEY+APOLLO_GRAPH_REF)。
选择一个安全级别(限制逐渐增强):
| 级别 | 配置 | 行为 |
|---|---|---|
| 审计(建议先用) | persisted_queries.log_unknown: true | 记录未注册的操作;不拒绝任何操作。在强制执行前,用于确认所有客户端都已注册。 |
| 安全名单 | safelist.enabled: true | 拒绝不在 PQL 中的操作。已注册的 ID 和完整字符串均可接受。 |
| 安全名单,仅限 ID | safelist.enabled: true + require_id: true | 拒绝未注册的操作,以及任何自由格式的操作字符串,即使该字符串已注册。 |
然后确认:
- 路由器是否已连接到 GraphOS? 安全名单需要从 GraphOS 获取 PQL(或使用离线许可证的
local_manifests)。 - 客户端是否已将其操作发布到 PQL(通过其 CI/CD 中的
rover persisted-queries publish)?如果没有,请先使用审计模式。 - 启用
safelist时,必须禁用 APQ(apq.enabled: false)——两者互斥。
配置键历史:自 v1.32.0 起,persisted_queries 为 GA(v1.25.0–v1.32.0 期间使用 preview_persisted_queries);所有 v2 版本均为 GA。请参阅 references/configuration.md → 持久化查询安全名单。
Connectors(仅限 v2)
- 子图名称和源名称(用作
connectors.sources.<subgraph>.<source>) - 可选的
$config值,用于 Connector 运行时配置 - 如果要迁移旧的 v2 预览版配置,请将
preview_connectors重命名为connectors
操作限制
提供调优建议:
Operation depth limit controls how deeply nested a query can be.
Router default: 100 (permissive — allows very deep queries)
Recommended starting point: 50
Lower values (15–25) are more secure but will reject legitimate queries
in schemas with deep entity relationships or nested fragments.
Higher values (75–100) are safer for compatibility but offer less
protection against depth-based abuse.
Tip: Run your router in warn_only mode first to see what depths your
real traffic actually uses, then tighten:
limits:
warn_only: true
What max_depth would you like? [default: 50]
同样的原则也适用于 max_height、max_aliases 和 max_root_fields。
遥测
- OTEL 收集器端点(默认:
http://otel-collector:4317) - Prometheus 监听端口(默认:
9090) - 跟踪采样率(默认:
0.1= 10%)
流量整形
- 面向客户端的速率限制容量(默认:1000 req/s)
- 路由器超时(默认:60s)
- 子图超时(默认:30s)
响应缓存(仅限 v2,v2.6.0+)
安全:存在数据泄露风险。 在生成任何响应缓存配置之前,必须询问用户哪些类型和字段会返回用户专属数据。缓存数据默认为共享 — 未设置
Cache-Control: private的子图响应对所有用户可见。用户专属子图必须返回Cache-Control: private,并在路由器上配置private_id。
- 询问:哪些子图提供用户专属数据?(例如:账户、个人资料、购物车)
- 询问:如何识别用户?(JWT
sub声明、会话令牌、API 密钥) - Redis URL(默认值:
redis://localhost:6379) - 默认 TTL(默认值:
5m) - 是否启用主动失效?如果是:失效监听地址和共享密钥
- 使用分区模板:
templates/v2/sections/response-caching.yaml - 关于安全要求、架构指令和高级配置,请参阅:
references/response-caching.md(从 Security 部分开始)
第 5 步:生成配置
- 从
templates/{version}/加载正确的版本模板 - 为受支持的分区功能组装分区模板,然后根据需要合并 APQ/订阅的基础模板片段
- 注入用户提供的参数
- 在顶部添加注释块,注明目标版本
第 6 步:验证
运行生成后检查清单:
- 配置中引用的所有环境变量均有说明
- CORS 来源不包含通配符(生产环境)
- 限流配置位于
router:(面向客户端),而不只是all:(子图) - JWT 使用
issuers(v2),而非issuer(v1),反之亦然 - 如果是生产环境:introspection=false、sandbox=false、subgraph_errors=false
- 已启用健康检查
- 已禁用主页(生产环境)
- 运行:如果 Router 二进制文件可用,执行
router config validate <file>
必需的验证关卡(始终运行)
生成或编辑任何 router.yaml 后,必须:
- 运行
validation/checklist.md,并报告每项检查清单的通过/未通过状态。 - 如果 Router CLI 可用,运行
router config validate <path-to-router.yaml>。 - 如果 Router CLI 不可用,明确说明这一点,并仍然完成检查清单。
- 验证完成前,不得将配置作为最终版本提供。
配置即代码(git + CI/CD)
router.yaml 是路由器对每个请求的约定 — 应将其视为应用程序代码,而不是运维工作中的事后考虑。每当生成或编辑配置时,都应引导用户采用以下工作流:
- 将
router.yaml提交到版本控制。 它应与服务一同存放在 git 中,并通过拉取请求审核变更。这样,你就能追踪 API 层中最关键安全文件的历史、责任归属和回滚记录。 - 绝不提交密钥。 不要将
APOLLO_KEY、JWKS URL、Redis URL 和失效密钥写入文件 — 使用${env.*}扩展引用它们,并在部署时注入。提交的文件应确保任何有仓库访问权限的人都可以安全读取。 - 在 CI 中验证。 每个 PR 都运行
router config validate router.yaml,以便格式错误或版本不匹配的配置在发布前导致构建失败。在 CI 中固定所用 Router 版本,使其与部署的版本一致。 - 将配置变更与架构检查配套进行。 架构变更通过
rover subgraph check/rover subgraph publish(rover技能)进行;配置变更则通过此 CI 验证关卡进行。两者都会作为同一部署的关卡。 - 在不同环境中使用同一个文件。 开发环境与生产环境的差异应通过环境变量表达,而不是使用不同的已提交文件,这样你审核过的内容就是实际运行的内容。
最简 CI 步骤(仅在用户提出要求时提供实际命令):
# Validate router config on every pull request
- run: router config validate router.yaml
第 7 步:条件式后续步骤交接
回答任何 Apollo Router 请求后(配置生成、编辑、验证或常规 Router 指导),判断用户是否已具备可运行所需的前提条件:
- GraphOS 管理路径:
APOLLO_KEY+APOLLO_GRAPH_REF,或 - 本地路径:已组合的
supergraph.graphql和可访问的子图
如果前提条件已具备,不要添加额外的交接说明。
如果前提条件缺失或未知,请以简洁的 后续步骤 交接作为结尾(最多 1-3 行),优先引导使用技能,且不包含命令:
- 建议使用
rover技能来组合或获取 supergraph schema。 - supergraph 就绪后,建议继续使用
apollo-router,通过生成的配置进行验证和运行。 - 如果缺少子图,建议使用
apollo-server、graphql-schema和graphql-operations技能进行脚手架搭建和测试。
除非用户明确要求,否则交接中不要包含原始 Shell 命令。
快速入门(优先使用技能)
- 使用此
apollo-router技能,为你的环境生成或优化router.yaml。 - 选择运行时路径:
- GraphOS 管理路径:提供
APOLLO_KEY和APOLLO_GRAPH_REF(无需在本地组合 supergraph)。 - 本地 supergraph 路径:使用
graphql-schema+apollo-server定义并运行子图,然后使用graphql-operations进行冒烟测试,接着使用rover技能组合或获取supergraph.graphql。
- GraphOS 管理路径:提供
- 使用此
apollo-router技能验证就绪状态(validation/checklist.md),并了解运行时启动所需的输入。
使用标准 Router 监听默认值时,默认端点仍为 http://localhost:4000。
如果用户要求可执行的 Shell 命令,请按要求提供。否则,快速入门指导应以技能为主。
运行模式
| 模式 | 命令 | 使用场景 |
|---|---|---|
| 本地 schema | router --supergraph ./schema.graphql | 开发、CI/CD |
| GraphOS 管理模式 | APOLLO_KEY=... APOLLO_GRAPH_REF=my-graph@prod router | 生产环境,自动更新 |
| 开发模式 | router --dev --supergraph ./schema.graphql | 本地开发 |
| 热重载 | router --hot-reload --supergraph ./schema.graphql | 无需重启即可应用 schema 变更 |
环境变量
| 变量 | 描述 |
|---|---|
APOLLO_KEY | GraphOS 的 API 密钥 |
APOLLO_GRAPH_REF | Graph 引用(graph-id@variant) |
APOLLO_ROUTER_CONFIG_PATH | router.yaml 的路径 |
APOLLO_ROUTER_SUPERGRAPH_PATH | supergraph schema 的路径 |
APOLLO_ROUTER_LOG | 日志级别(off、error、warn、info、debug、trace) |
APOLLO_ROUTER_LISTEN_ADDRESS | 覆盖监听地址 |
参考文件
- 配置 — YAML 配置参考
- 请求头 — 请求头传递与操作
- 插件 — Rhai 脚本和协处理器
- 遥测 — 追踪、指标和日志记录
- 连接器 — Router v2 连接器配置
- 响应缓存 — 实体/根字段缓存、失效处理和可观测性(仅限 v2)
- 故障排除 — 常见问题和解决方案
- 差异映射 — v1 ↔ v2 配置差异
- 验证清单 — 生成后的检查
CLI 参考
router [OPTIONS]
Options:
-s, --supergraph <PATH> Path to supergraph schema file
-c, --config <PATH> Path to router.yaml configuration
--dev Enable development mode
--hot-reload Watch for schema changes
--log <LEVEL> Log level (default: info)
--listen <ADDRESS> Override listen address
-V, --version Print version
-h, --help Print help
基本规则
- 生成配置前,始终确定目标 Router 版本(v1 或 v2)
- 新项目默认使用 v2
- 生成的配置顶部始终包含注释块,注明目标版本
- 本地开发始终使用
--dev模式(启用内省和沙箱) - 生产环境始终禁用内省、沙箱和主页
- 生产环境优先使用 GraphOS 托管模式(自动更新、指标)
- 使用基于文件的 schema 进行本地开发时,使用
--hot-reload - 绝不在日志或版本控制中暴露
APOLLO_KEY - 所有机密和敏感配置均使用环境变量(
${env.VAR}) - 复杂设置优先使用 YAML 配置,而不是命令行参数
- 部署到生产环境前,先在本地测试配置变更
- 如果用户在生产环境中启用
allow_any_origin或通配符 CORS,发出警告 - 对于 v1 → v2 迁移,建议使用
router config upgrade router.yaml,而不是从头重新生成 - 每次生成或编辑 Router 配置后,都必须运行
validation/checklist.md - Router CLI 可用时,必须运行
router config validate <file> - 如果无法运行 CLI 验证(例如缺少 Router 二进制文件),必须明确说明
- 如果运行时前置条件缺失或未知,必须附上一段简短的条件式交接说明
- 该交接说明必须优先引导使用技能,除非用户明确要求命令,否则避免提供原始 shell 命令
- Quick Start 指引必须优先引导使用技能,除非用户明确要求命令,否则不提供命令
- 必须说明,只有本地 supergraph 路径需要 Rover;GraphOS 托管运行时不需要本地 Rover 组合
- 默认起始值使用
max_depth: 50,不要用 15(限制过严)或 100(限制过宽) - 初次推出限制时,建议使用
warn_only: true,先观察真实流量,再强制执行 - 仅当
ROUTER_VERSION=v2时才提供 Response Caching(需要 v2.6.0+) - Redis URL、密码和失效共享密钥始终使用
${env.*} - 生产配置中绝不启用
response_cache.debug: true - 生产环境建议结合使用 Cache-Control 标头(被动 TTL)和 @cacheTag(主动失效)
- 生成响应缓存配置前,始终询问哪些字段会返回用户专属数据——绝不假设所有数据都适合共享缓存
- 对于提供用户专属数据的子图,始终配置
private_id,并确保这些子图返回Cache-Control: private(在 Apollo Server 中通过@cacheControl(scope: PRIVATE)设置,或在其他框架中直接设置标头) - 生成响应缓存配置时,绝不忽略私有数据问题——如果用户表示“没有用户专属数据”,必须先明确确认再继续
- 失效端点始终绑定到
127.0.0.1,生产环境绝不绑定到0.0.0.0 - 绝不混淆 APQ 与持久化查询安全列表机制——APQ(
apq)是带宽优化手段,不具备安全价值;安全列表(persisted_queries.safelist)才是操作允许列表。如果用户询问如何“限制哪些查询可以执行”,应引导其使用安全列表,而不是 APQ - 启用
persisted_queries.safelist时,始终禁用 APQ(apq.enabled: false)——二者互斥 - 建议先以审计模式(
log_unknown: true)启用持久化查询,确认所有客户端均已注册,再启用safelist.enabled - 必须说明,持久化查询安全列表需要连接 GraphOS 的 Router(通过
APOLLO_KEY+APOLLO_GRAPH_REF获取 PQL,或为离线许可证使用local_manifests) - 使用
persisted_queries(GA,v1.32.0+ 和所有 v2),而不是preview_persisted_queries(v1.25.0–v1.32.0) - 将全局
authorization.require_authentication和声明式指令视为不同层级:前者控制整个请求的访问,后者(@authenticated/@requiresScopes/@policy)在字段和类型级别进行筛选 - 必须说明,声明式授权指令需要连接 GraphOS 的 Router(v1.29.1+;Developer/Standard 计划需要 v2.6.0+)以及 claims 来源(JWT 身份验证,或用于填充
apollo::authentication::jwt_claims的 coprocessor) - 注意,授权指令默认已启用——
authorization.directives.enabled: false只会将其关闭;绝不暗示需要配置才能“启用”它们 - 必须说明,
@policy还需要在 Supergraph 阶段使用 Rhai 脚本或 coprocessor 来评估apollo::authorization::required_policies - 授权指令必须放在子图 schema 中,绝不能放在
router.yaml中——Router 配置只能启用或禁用该功能 - 建议将
router.yaml提交到版本控制,并在 CI 中对每个 PR 运行router config validate;所有机密都通过${env.*}引用,并在部署时注入 - 绝不将机密(
APOLLO_KEY、JWKS/Redis URL、失效密钥)提交到配置文件中;提交的router.yaml必须可以安全地与任何拥有仓库访问权限的人共享