Mode d’emploi
- Copiez la commande et examinez le paquet avant de l’installer dans votre environnement agent.
- Consultez le document original pour les outils, identifiants et environnements requis.
- Décrivez les entrées et le livrable souhaité ; comparez la sortie aux sources.
npx skills add https://github.com/apollographql/skills --skill apollo-router-plugin-creatorAvant de commencer
- L’installation n’inclut ni abonnement au modèle, ni quota API, ni accès aux fichiers.
- Étoiles et installations reflètent l’activité, pas un test indépendant de qualité ou de sécurité.
Rendu depuis le dépôt source en conservant titres, exemples, code, tableaux, liens et images.
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:
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::BoxServiceIndividual 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_servicerequest - After parsing, before planning →
supergraph_servicerequest - After planning, before execution →
execution_servicerequest - Before/after each subgraph call →
subgraph_service - Final response to client →
router_serviceresponse
See 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:
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:
#[derive(Debug, Clone, Default, Deserialize, JsonSchema)]
struct MyPluginConfig {
/// Enable the plugin
enabled: bool,
// Add other configuration fields as needed
}Step 3: Define Plugin Struct
#[derive(Debug)]
struct MyPlugin {
configuration: MyPluginConfig,
}Step 4: Implement Plugin Trait
Implement the Plugin trait with the required Config type and new constructor:
#[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 for details.
Example service hook:
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:
register_plugin!("acme", "my_plugin", MyPlugin);Step 7: Add Module to mod.rs
In src/plugins/mod.rs, add your module:
pub mod my_plugin;Step 8: Configure in YAML
Enable your plugin in the router configuration:
plugins:
acme.my_plugin:
enabled: trueCommon 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.
Prerequisites
It is advised to have the 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 - Detailed service hook implementations
- references/existing-plugins.md - Index of existing plugins
- references/examples.md - Full code examples and testing patterns
- Apollo Router plugins: https://github.com/apollographql/router/tree/dev/apollo-router/src/plugins




