Skip to main content
skill CX Codex

apollo-router-plugin-creator — Claude Code skill: how to install

Helps build native Rust plugins for Apollo Router. It assists with request lifecycle hooks and modifying existing router extensions.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add apollographql/skills --skill apollo-router-plugin-creator -a claude-code
Open on GitHub

What apollo-router-plugin-creator does

This skill guides developers through creating and editing native Rust plugins for Apollo Router. It explains the request pipeline, from HTTP conversion at router_service to sub-operation routing at subgraph_service.

The agent inspects and edits code using Read, Write, Edit, Glob, and Grep. It implements the primary hook interfaces: router_service, supergraph_service, execution_service, and subgraph_service.

Your deployment requires an Apollo Router build compiled with native plugin support. Otherwise, custom Rust plugins cannot run.

What it helps with

  • scaffold native Rust plugins for Apollo Router
  • add subgraph_service hooks to route operations
  • modify lifecycle handlers in existing router plugins
  • inspect GraphQL request execution flow across router stages

Example prompts for the agent

  • create a new plugin for Apollo Router
  • add a subgraph_service hook to my router plugin
  • modify the auth plugin to inspect supergraph_service requests

How to install apollo-router-plugin-creator

1Skills CLI (Vercel)

npx skills add apollographql/skills --skill apollo-router-plugin-creator -a claude-code

2Manually: put the files in place

~/.claude/skills/apollo-router-plugin-creator/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/apollo-router-plugin-creator/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about apollo-router-plugin-creator

How to install apollo-router-plugin-creator in Claude Code?

Run npx skills add apollographql/skills --skill apollo-router-plugin-creator -a claude-code in your terminal.

What does apollo-router-plugin-creator do?

It guides the creation and modification of Apollo Router native Rust plugins, helping you implement service hooks across the request lifecycle.

What are the compatibility requirements?

It requires an Apollo Router environment built with native plugin support to run the compiled extensions.

Source text

SKILL.md · MIT
---
name: apollo-router-plugin-creator
description: >
  Guide for writing Apollo Router native Rust plugins. Use this skill when:
  (1) users want to create a new router plugin,
  (2) users want to add service hooks (router_service, supergraph_service, execution_service, subgraph_service),
  (3) users want to modify an existing router plugin,
  (4) users need to understand router plugin patterns or the request lifecycle.
  (5) triggers on requests like "create a new plugin", "add a router plugin", "modify the X plugin", or "add subgraph_service hook".
license: MIT
allowed-tools: Read Write Edit Glob Grep
metadata:
  author: apollographql
  version: "1.0.0"
  compatibility: "Requires Apollo Router with native plugin support"
---

# Apollo Router Plugin Creator

Create native Rust plugins for Apollo Router.

## Request Lifecycle

```
┌────────┐             ┌────────────────┐                                   ┌────────────────────┐               ┌───────────────────┐       ┌─────────────────────┐
│ 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:**
```rust
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](references/service-hooks.md) for implementation patterns.

## Quick Start

### Step 1: Create Plugin File

Create a new file `src/plugins/my_plugin.rs` with required imports:

```rust
use std::ops::ControlFlow;
use apollo_router::plugin::{Plugin, PluginInit};
use apollo_router::register_plugin;
use apollo_router::services::{router, subgraph, supergraph};
use schemars::JsonSchema;
use serde::Deserialize;
use tower::{BoxError, ServiceBuilder, ServiceExt};

const PLUGIN_NAME: &str = "my_plugin";
```

### Step 2: Define Configuration Struct

Every plugin needs a configuration struct with `Deserialize` and `JsonSchema` derives. The `JsonSchema` enables configuration validation in editors:

```rust
#[derive(Debug, Clone, Default, Deserialize, JsonSchema)]
struct MyPluginConfig {
  /// Enable the plugin
  enabled: bool,
  // Add other configuration fields as needed
}
```

### Step 3: Define Plugin Struct

```rust
#[derive(Debug)]
struct MyPlugin {
  configuration: MyPluginConfig,
}
```

### Step 4: Implement Plugin Trait

Implement the `Plugin` trait with the required `Config` type and `new` constructor:

```rust
#[async_trait::async_trait]
impl Plugin for MyPlugin {
  type Config = MyPluginConfig;

  async fn new(init: PluginInit<Self::Config>) -> Result<Self, BoxError> {
    Ok(MyPlugin { configuration: init.config })
  }

  // Add service hooks based on your needs (see "Choosing a Service Hook" section)
}
```

### Step 5: Add Service Hooks

Choose which service(s) to hook based on your requirements, see [Service Overview](#service-overview) for details.

Example service hook:
```rust
fn supergraph_service(&self, service: supergraph::BoxService) -> supergraph::BoxService {
  if !self.configuration.enabled {
    return service;
  }

  ServiceBuilder::new()
    .map_request(|req| { /* transform request */ req })
    .map_response(|res| { /* transform response */ res })
    .service(service)
    .boxed()
}
```

### Step 6: Register Plugin

At the bottom of your plugin file, register it with the router:

```rust
register_plugin!("acme", "my_plugin", MyPlugin);
```

### Step 7: Add Module to mod.rs

In `src/plugins/mod.rs`, add your module:

```rust
pub mod my_plugin;
```

### Step 8: Configure in YAML

Enable your plugin in the router configuration:

```yaml
plugins:
  acme.my_plugin:
    enabled: true
```

## Common Patterns

For implementation patterns and code examples, see [references/service-hooks.md](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](https://github.com/apollographql/router/tree/dev/apollo-router/src/plugins):

| 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](references/examples.md).

## Prerequisites

It is advised to have the [rust-best-practices](https://skills.sh/apollographql/skills/rust-best-practices) skill installed for writing idiomatic Rust code when developing router plugins. If installed, follow those best practices when generating or modifying plugin code.

## Resources

- [references/service-hooks.md](references/service-hooks.md) - Detailed service hook implementations
- [references/existing-plugins.md](references/existing-plugins.md) - Index of existing plugins
- [references/examples.md](references/examples.md) - Full code examples and testing patterns
- Apollo Router plugins: https://github.com/apollographql/router/tree/dev/apollo-router/src/plugins

© apollographql · MIT · apollographql/skills

Similar skills

Everything for Backend and APIs →

From the same set11

graphql-schema Guides GraphQL SDL schema design following Apollo best practices. Useful when creating schema.graphql, adding mutations, or setting up pagination. CX Codex +1 4,000installs graphql-operations A skill that keeps your agent writing GraphQL queries, mutations and fragments against the real schema. Useful when it starts inventing field names. CX Codex +1 3,600installs apollo-server Guides AI agents in building GraphQL APIs with Apollo Server 5.x. Useful when setting up schemas, writing resolvers, and configuring authentication. CX Codex +1 2,800installs apollo-connectors Walks an agent through wiring a REST API into a GraphQL supergraph with @source and @connect. Best for quick edits to an existing Connectors schema. CX Codex +1 2,200installs apollo-federation Guides an agent through Apollo Federation subgraph schemas: directives, entities with @key, composition errors. Handy when a supergraph spans several GraphQL services. CX Codex +1 1,900installs apollo-router A skill that writes version-correct router.yaml for Apollo Router v1.x and v2.x and flags the sections where the two schemas diverge. CX Codex +1 1,800installs apollo-kotlin A skill that walks the agent through Apollo Kotlin setup in a Gradle project: schema, codegen, an ApolloClient with auth and cache, plus operations. CX Codex +1 1,700installs apollo-ios Walks your agent through adding Apollo iOS to a Swift project: codegen config, client setup, queries, subscriptions and mock-based tests. CX Codex +1 1,100installs

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor