Labsco
apollographql logo

apollo-router-plugin-creator

β˜… 90

by apollographql Β· part of apollographql/skills

Create native Rust plugins for Apollo Router.

πŸ”₯πŸ”₯πŸ”₯βœ“ VerifiedFreeQuick setup
🧩 One of 7 skills in the apollographql/skills package β€” works on its own, and pairs well with its siblings.

Create native Rust plugins for Apollo Router.

Inspect the full instructions your agent will receiveExpand

This is the exact playbook injected into your agent when the skill activates β€” shown here so you can audit it before installing. You don't need to read it to use the skill.

by apollographql

Create native Rust plugins for Apollo Router. npx skills add https://github.com/apollographql/skills --skill apollo-router-plugin-creator Download ZIPGitHub90

Apollo Router Plugin Creator

Create native Rust plugins for Apollo Router.

Request Lifecycle

Copy & paste β€” that's it
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Client β”‚ β”‚ Router Service β”‚ β”‚ Supergraph Service β”‚ β”‚ Execution Service β”‚ β”‚ Subgraph Service(s) β”‚
β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
 β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ Sends request β”‚ β”‚ β”‚ β”‚
 │──────────────────────────▢ β”‚ β”‚ β”‚
 β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ β”‚ Converts raw HTTP request to GraphQL/JSON request β”‚ β”‚ β”‚
 β”‚ │──────────────────────────────────────────────────────▢ β”‚ β”‚
 β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ β”‚ β”‚ Initiates query plan execution β”‚ β”‚
 β”‚ β”‚ │───────────────────────────────────▢ β”‚
 β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ β”‚ β”‚ β”Œpar [Initiates sub-operation]───────┐
 β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ β”‚ β”‚ β”‚ β”‚ Initiates sub-operation β”‚ β”‚
 β”‚ β”‚ β”‚ β”‚ │────────────────────────────▢ β”‚
 β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ β”‚ β”‚ β”œ[Initiates sub-operation]β•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ”€
 β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ β”‚ β”‚ β”‚ β”‚ Initiates sub-operation β”‚ β”‚
 β”‚ β”‚ β”‚ β”‚ │────────────────────────────▢ β”‚
 β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ β”‚ β”‚ β”œ[Initiates sub-operation]β•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ”€
 β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ β”‚ β”‚ β”‚ β”‚ Initiates sub-operation β”‚ β”‚
 β”‚ β”‚ β”‚ β”‚ │────────────────────────────▢ β”‚
 β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
 β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ β”‚ β”‚ Assembles and returns response β”‚ β”‚
 β”‚ β”‚ β—€β•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ”‚ β”‚
 β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ β”‚ Returns GraphQL/JSON response β”‚ β”‚ β”‚
 β”‚ β—€β•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ”‚ β”‚ β”‚
 β”‚ β”‚ β”‚ β”‚ β”‚
 β”‚ Returns HTTP response β”‚ β”‚ β”‚ β”‚
 β—€β•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ•Œβ”‚ β”‚ β”‚ β”‚
 β”‚ β”‚ β”‚ β”‚ β”‚
β”Œβ”€β”€β”€β”€β”΄β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Client β”‚ β”‚ Router Service β”‚ β”‚ Supergraph Service β”‚ β”‚ Execution Service β”‚ β”‚ Subgraph Service(s) β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Service Hooks

Service Overview

Service Description router_service Runs at the very beginning and very end of the HTTP request lifecycle.For example, JWT authentication is performed within the RouterService.Define router_service if your customization needs to interact with HTTP context and headers. It doesn't support access to the body property supergraph_service Runs at the very beginning and very end of the GraphQL request lifecycle.Define supergraph_service if your customization needs to interact with the GraphQL request or the GraphQL response. For example, you can add a check for anonymous queries. execution_service Handles initiating the execution of a query plan after it's been generated.Define execution_service if your customization includes logic to govern execution (for example, if you want to block a particular query based on a policy decision). subgraph_service Handles communication between the router and your subgraphs.Define subgraph_service to configure this communication (for example, to dynamically add HTTP headers to pass to a subgraph).Whereas other services are called once per client request, this service is called once per subgraph request that's required to resolve the client's request. Each call is passed a subgraph parameter that indicates the name of the corresponding subgraph.

Signatures:

Copy & paste β€” that's it
fn router_service(&self, service: router::BoxService) -> router::BoxService
fn supergraph_service(&self, service: supergraph::BoxService) -> supergraph::BoxService
fn execution_service(&self, service: execution::BoxService) -> execution::BoxService
fn subgraph_service(&self, name: &str, service: subgraph::BoxService) -> subgraph::BoxService

Individual Hooks (Tower Layers)

Use ServiceBuilder to compose these hooks within any service:

Hook Purpose Sync/Async map_request(fn) Transform request before proceeding Sync map_response(fn) Transform response before returning Sync checkpoint(fn) Validate/filter, can short-circuit Sync checkpoint_async(fn) Async validation, can short-circuit Async buffered() Enable service cloning (needed for async) - instrument(span) Add tracing span around service - rate_limit(num, period) Control request throughput - timeout(duration) Set operation time limit -

Choosing a Service Hook

By data needed:

  • HTTP headers only β†’ router_service

  • GraphQL query/variables β†’ supergraph_service

  • Query plan β†’ execution_service

  • Per-subgraph control β†’ subgraph_service

By timing:

  • Before GraphQL parsing β†’ router_service request

  • After parsing, before planning β†’ supergraph_service request

  • After planning, before execution β†’ execution_service request

  • Before/after each subgraph call β†’ subgraph_service

  • Final response to client β†’ router_service response

See references/service-hooks.md for implementation patterns.

Common Patterns

For implementation patterns and code examples, see references/service-hooks.md:

  • Enable/disable pattern

  • Request/response transformation (map_request, map_response)

  • Checkpoint (early return/short-circuit)

  • Context passing between hooks

  • Async operations (checkpoint_async, buffered)

  • Error response builders

Examples

Apollo Router Examples

Located in the Apollo Router plugins directory:

Plugin Service Hook Pattern Description forbid_mutations.rs execution_service checkpoint Simple gate on query plan expose_query_plan.rs execution + supergraph Context passing Multi-service coordination cors.rs router_service HTTP layer CORS handling at HTTP level headers/ subgraph_service Layer composition Complex header manipulation

For full code examples and testing patterns, see references/examples.md.

Resources