apollo-router-plugin-creator

Crie plugins nativos em Rust para o Apollo Router.

npx skills add https://github.com/apollographql/skills --skill apollo-router-plugin-creator

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

ServiceDescription
router_serviceRuns 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_serviceRuns 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_serviceHandles 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_serviceHandles 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::BoxService

Individual Hooks (Tower Layers)

Use ServiceBuilder to compose these hooks within any service:

HookPurposeSync/Async
map_request(fn)Transform request before proceedingSync
map_response(fn)Transform response before returningSync
checkpoint(fn)Validate/filter, can short-circuitSync
checkpoint_async(fn)Async validation, can short-circuitAsync
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.

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: true

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:

PluginService HookPatternDescription
forbid_mutations.rsexecution_servicecheckpointSimple gate on query plan
expose_query_plan.rsexecution + supergraphContext passingMulti-service coordination
cors.rsrouter_serviceHTTP layerCORS handling at HTTP level
headers/subgraph_serviceLayer compositionComplex 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

Mais skills de apollographql

apollo-federation
apollographql
O Apollo Federation permite compor múltiplas APIs GraphQL (subgrafos) em um supergrafo unificado.
apollo-ios
apollographql
Apollo iOS é um cliente GraphQL fortemente tipado para plataformas Apple. Ele gera tipos Swift a partir das suas operações e schema GraphQL, e inclui um cliente async/await, um cache normalizado (em memória ou com suporte a SQLite), um transporte HTTP baseado em interceptadores plugáveis que lida com queries, mutations e assinaturas multipart, e um transporte WebSocket opcional (graphql-transport-ws) que pode transportar qualquer tipo de operação.
apollo-router
apollographql
O Apollo Router é um roteador de grafos de alto desempenho escrito em Rust para executar supergrafos do Apollo Federation 2. Ele fica na frente dos seus subgrafos e lida com planejamento de consultas, execução e composição de respostas.
apollo-server
apollographql
Guia completo para construir servidores GraphQL com Apollo Server 5.x em diferentes frameworks. Aborda definição de esquemas, resolvers, configuração de contexto e tratamento de erros com suporte a TypeScript. Suporta modo standalone para prototipagem e integrações com Express, Fastify, Koa e ambientes serverless. Inclui padrões de resolvers, autenticação/autorização, plugins, DataLoader para prevenção de N+1 e técnicas de otimização de desempenho. Fornece documentação de referência para fontes de dados, erros...
graphql-operations
apollographql
Guia de melhores práticas para escrever operações GraphQL eficientes e type-safe, organizando-as com fragments. Aborda queries, mutations, subscriptions e fragments com convenções de nomenclatura, sintaxe de variáveis e uso de diretivas. Enfatiza princípios fundamentais: solicitar apenas os campos necessários, nomear todas as operações, usar variáveis em vez de valores fixos e incluir campos de id para capacidade de cache. Recomenda colocar fragments junto com componentes e usar as diretivas @include / @skip para campos condicionais...
graphql-schema
apollographql
Guia de melhores práticas da indústria para projetar schemas GraphQL intuitivos, performáticos e de fácil manutenção. Aborda princípios fundamentais de design, incluindo organização de tipos centrada no cliente, padrões explícitos de nulidade e estratégias de evolução com compatibilidade reversa. Fornece documentação de referência sobre tipos, convenções de nomenclatura, paginação baseada em cursor, modelagem de erros e considerações de segurança. Inclui padrões práticos para interfaces, uniões, tipos de entrada, mutações e estratégias de ID com exemplos de código...
rover
apollographql
CLI Apollo Rover para gerenciar esquemas GraphQL, federação e desenvolvimento local de supergraph. Publique, busque e valide esquemas de subgraph; componha supergraphs federados localmente ou via GraphOS. Inclui verificação de esquema (validação pré-implantação), linting e introspecção de servidores em execução. O comando rover dev inicia um Router local com composição automática de esquema para fluxos de desenvolvimento. Suporta padrões de CI/CD com validação check-before-publish e saída JSON para scripts. Requer...
rust-best-practices
apollographql
Padrões de codificação idiomáticos em Rust baseados no manual de melhores práticas da Apollo GraphQL. Abrange nove áreas principais: estilos e expressões idiomáticas de codificação, linting com clippy, otimização de desempenho, tratamento de erros, padrões de teste, genéricos e dispatch, padrão de estado de tipo, documentação e segurança de ponteiros. Enfatiza borrowing em vez de clonagem, tratamento de erros baseado em Result com thiserror/anyhow e perfilamento de desempenho com builds de release. Inclui orientação de referência rápida sobre padrões de ownership, prevenção de pânicos,...