Extending the Router
Hive Router is designed to be flexible and extensible, allowing you to customize its behavior to fit your specific needs. This guide demonstrates how to extend the router’s functionality using custom plugins written in Rust.
For technical details and API reference, see the Router Plugin System documentation.
Creating a Custom Plugin
Hive Router is built using Rust, which allows for high performance and safety. One of the powerful features of Hive Router is the ability to create custom builds with your own Rust plugins. This enables you to add new capabilities or modify existing ones to better suit your requirements.
Create a new Rust project
First, ensure you have the necessary development environment set up for Rust.
Next, create a new Rust project for your custom router:
cargo new --bin my_custom_router
cd my_custom_routerInstall Dependencies
Add hive-router and serde as dependencies in your Cargo.toml file:
[dependencies]
hive-router = "<HIVE_ROUTER_VERSION>" # see https://crates.io/crates/hive-router for latest version
serde = "1"main and router entrypoint
Next, you need to create an entrypoint for your custom router. This is where you’ll initialize the
router and register your plugins. Create a new file src/main.rs and add the following code:
use hive_router::{
configure_global_allocator, RouterGlobalAllocator,
error::RouterInitError, init_rustls_crypto_provider, router_entrypoint,
PluginRegistry,
};
// Configure the global allocator that's used by Hive Router
configure_global_allocator!();
#[hive_router::main]
async fn main() -> Result<(), RouterInitError> {
// Configure TLS so your router will be able to make HTTPS requests
// By default, Router is using the system's default certificate store.
init_rustls_crypto_provider();
// Start the Hive Router with the plugin registry
router_entrypoint(PluginRegistry::new()).await
}Configure your Router
To use the Router, you’ll need to create a router.config.yaml file in the root of your project.
This file will contain the configuration for your router, including the supergraph source and any plugins you want to use.
This configuration file must also point to a valid, composed Supergraph file.
If you already have a Supergraph available for testing, place it in your project directory. Alternatively, you can use the example supergraph as a starting point:
curl -sSL https://federation-demo.theguild.workers.dev/supergraph.graphql > supergraph.graphqlThen, point to your Supergraph in your router.config.yaml:
supergraph:
source: file
path: ./supergraph.graphqlHive Router supports loading the Supergraph from additional sources. See the Supergraph Sources documentation for details.
Run your custom router
At this point, you should be able to run your router by executing the following command:
cargo runBy default, the Router serves on port 4000. Open
http://localhost:4000/graphql in your browser to access the
interactive GraphQL playground.
Create a custom plugin
Now you can create a custom plugin by implementing the
RouterPlugin trait.
Then, create a src/plugin.rs file with the following template:
use hive_router::{
async_trait,
plugins::{
hooks::{
on_graphql_params::{OnGraphQLParamsStartHookPayload, OnGraphQLParamsStartHookResult}, on_plugin_init::{OnPluginInitPayload, OnPluginInitResult}
},
plugin_trait::{RouterPlugin, StartHookPayload},
},
};
#[derive(Default)]
pub struct MyPlugin;
#[async_trait]
impl RouterPlugin for MyPlugin {
type Config = ();
fn plugin_name() -> &'static str {
"my_plugin"
}
fn on_plugin_init(payload: OnPluginInitPayload<Self>) -> OnPluginInitResult<Self> {
payload.initialize_plugin_with_defaults()
}
async fn on_graphql_params<'exec>(
&'exec self,
payload: OnGraphQLParamsStartHookPayload<'exec>,
) -> OnGraphQLParamsStartHookResult<'exec> {
println!("Received GraphQL operation: {:?}", payload.graphql_params.query);
payload.proceed()
}
}The plugin above uses the Plugin System Hooks API and hooks into
the on_graphql_params phase to print the received GraphQL operation to the log.
You can find a complete plugin template in the Router GitHub repository.
Register your plugin
Now, register your plugin in main.rs:
use hive_router::{
error::RouterInitError, init_rustls_crypto_provider, ntex, router_entrypoint,
RouterGlobalAllocator, configure_global_allocator, PluginRegistry,
};
+ mod plugin;
+ use plugin::MyPlugin;
configure_global_allocator!();
#[hive_router::main]
async fn main() -> Result<(), RouterInitError> {
init_rustls_crypto_provider();
router_entrypoint(
PluginRegistry::new()
+ .register::<MyPlugin>()
).await
}Enable and configure your plugin
With the plugin registered, the Router is ready to use it. Enable and configure your plugin in the
router.config.yaml file:
supergraph:
source: file
path: ./supergraph.graphql
plugins:
my_plugin:
enabled: trueTry your plugin
You can now compile and run your Router again:
cargo runUse the interactive GraphQL playground at
http://localhost:4000/graphql to run a query. If your plugin is
registered, configured, and enabled correctly, any GraphQL operation will print a log message as
defined in the on_graphql_params hook of the custom plugin.
The simplest GraphQL operation you can run without requiring any subgraphs to be running is:
query testQuery {
__typename
}Build your Router
Now that you have a custom plugin that extends the Router’s behavior, you’ll need to compile it in release mode to use it in production.
To do that, verify that your Cargo.toml file has a defined binary and entrypoint:
[[bin]]
name = "hive_router_with_my_plugin" # Name of the binary
path = "src/main.rs"Then build using the Rust compiler in release mode:
cargo build --releaseYour artifact will now be located in ./target/release/hive_router_with_my_plugin and you can run
it as-is.
Distribute your custom Router
We recommend wrapping your custom Router in a Docker image and building it using a Dockerfile:
# Use the official Rust image as the base image
# Please consider to pin the Rust version
FROM rust:latest
# Set the working directory inside the container
WORKDIR /app
# Copy the entire project into the container
COPY . .
# Build the project in release mode
RUN cargo build --release
# Expose the port that the router will run on
EXPOSE 4000
# Run the custom router binary
ENTRYPOINT ["./target/release/hive_router_with_my_plugin"]Then, run the following Docker build command:
docker build -t my-custom-router .After the image is built, you can run a container from it:
docker run \
-p 4000:4000 \
-v ./supergraph.graphql:/app/supergraph.graphql \
-v ./router.config.yaml:/app/router.config.yaml \
my-custom-routerAdditional Resources
The following links and examples can help you implement custom plugins and extend the Router in different ways.