Join us for GraphQL Summit, October 10-12 in San Diego. Use promo code ODYSSEY for $400 off your pass.
Docs
Launch GraphOS Studio

Creating a custom Apollo Router binary


⚠️ Native Rust plugins are an advanced feature of the Apollo Router. We do not recommend creating them for the following reasons:

  • Native plugins require familiarity with programming in Rust.
  • Native plugins require compiling a custom binary from source, which can introduce unexpected behavior in your router that's difficult to diagnose and support.

For most router customizations, we recommend instead creating a Rhai script or external coprocessor. Both of these customization types provide strong separation of concerns and fault isolation.

If a native plugin seems necessary for your use case, please open an issue so we can investigate adding the required functionality to the stock binary.

Note: The Apollo is made available under the Elastic License v2.0 (ELv2). This applies to its source code and all distributions. For details, see our licensing page.

Prerequisites

To compile the Apollo , you need to have the following installed:

After you install the above, also install the cargo-xtask and cargo-scaffold crates:

cargo install cargo-xtask
cargo install cargo-scaffold

1. Create a new project

  1. Use the cargo-scaffold command to create a project for your custom :

    cargo-scaffold scaffold https://github.com/apollographql/router.git -r apollo-router-scaffold/templates/base -t main
  2. The cargo-scaffold command prompts you for some configuration settings. For the purposes of this tutorial, set your project's name to starstuff.

  3. After your project is created, change to the starstuff directory:

    cd starstuff

The generated project has the following layout:

starstuff
├── Cargo.toml # Dependencies are declared here
├── README.md
├── router.yaml # Router yaml config
├── src
│ ├── main.rs # Entry point
│ └── plugins # Custom plugins are located here
│ └── mod.rs
└── xtask # Build support files
├── Cargo.toml
└── src
└── main.rs

The Apollo uses an auto-discovery mechanism for plugins, so any plugins you add via dependency are automatically available to the Router at runtime.

2. Compile the router

Create a debug build of the Apollo with the following command:

cargo build

The resulting debug binary is located in target/debug/router.

To create a release build for production environments, use this command instead:

cargo build --release

The resulting release binary is now located in target/release/router.

3. Run the compiled binary

Now you can test out your compiled with an example .

  1. Download the example with the following command:

    curl -sSL https://supergraph.demo.starstuff.dev/ > supergraph-schema.graphql
  2. Run the and provide the example like so:

    cargo run -- --hot-reload --config router.yaml --supergraph supergraph-schema.graphql

    During development, it's helpful to use cargo run to run the .

If you're using managed federation, you set the APOLLO_KEY and APOLLO_GRAPH_REF environment s instead of specifying the as a file. For details, see this section.

4. Create a plugin

  1. From within your project directory, scaffold a new plugin with the following command:

    cargo router plugin create hello_world
  2. The command prompts you to choose a starting template:

    Select a plugin template:
    > "basic"
    "auth"
    "tracing"

    The available templates are:

    • basic - a barebones plugin
    • auth - an authentication plugin for making an external call
    • tracing - a telemetry plugin that adds a custom metric span and a log message

    For the purposes of this tutorial, choose basic.

  3. Add configuration options for the created plugin to your router.yaml file:

    router.yaml
    plugins:
    starstuff.hello_world:
    message: "starting my plugin"
  4. Run the again:

    cargo run -- --hot-reload --config router.yaml --supergraph supergraph-schema.graphql

    This time, you should see a log line like the following:

    2022-05-21T09:16:33.160288Z INFO router::plugins::hello_world: starting my plugin

Nice work! You now have a custom binary with an associated plugin. Next, you can extend the plugin with the functionality you need or add more plugins.

Removing a plugin

To remove a previously added plugin from your project, use the following command:

cargo router plugin remove hello_world

Note that depending on the structure of your plugin, the command might fail to remove all of its associated files.

Memory allocator

On Linux the apollo-router crate sets jemalloc as the global memory allocator for Rust to reduce memory ation. Future versions may do so on more platforms, or switch to yet a different allocator. This is enabled by default and controlled by a global-allocator Cargo feature flag. If you want to choose a different allocator, disable it in your Cargo.toml:

[dependencies]
apollo-router = {version = "[…]", default-features = false}

If you make a library crate, also specify default-features = false in order to leave the choice open for the eventual executable crate. (Cargo default features are only disabled if all dependents specify default-features = false.)

Docker

You can use the provided Dockerfile to build a release container.

Make sure your is configured to listen to 0.0.0.0 so you can query it from outside the container:

supergraph:
listen: 0.0.0.0:4000

Use your APOLLO_KEY and APOLLO_GRAPH_REF environment s to run the in managed federation.

docker build -t my_custom_router .
docker run -e APOLLO_KEY="your apollo key" -e APOLLO_GRAPH_REF="your apollo graph ref" my_custom_router

Otherwise add a COPY step to the Dockerfile, and edit the entrypoint:

# Copy configuration for docker image
COPY router.yaml /dist/config.yaml
# Copy supergraph for docker image
COPY my_supergraph.graphql /dist/supergraph.graphql
# [...] and change the entrypoint
# Default executable is the router
ENTRYPOINT ["/dist/router", "-s", "/dist/supergraph.graphql"]
Previous
Native Rust plugins
Edit on GitHubEditForumsDiscord