Earlier this year we introduced the first version of Grafbase Gateway hooks, which lets you extend the gateway's functionality with custom logic. Today we are excited to announce the Grafbase Gateway Hooks crate grafbase-hooks, a Rust SDK for creating custom hooks for Grafbase Gateway.
While the first version required copying a WIT file and carefully implementing your hooks against the file's type definitions, the SDK simplifies the process by providing helpful traits and types. The SDK also includes macros for deriving the required traits for your hooks and registering them with the gateway.
To get started with the Grafbase Gateway Hooks SDK, install Rust, create a new library and install the SDK:
cargo new --lib my-hooks
cd my-hooks
cargo add grafbase-hooks
Create a struct that implements the Hooks
trait and use the grafbase_hooks
macro and register_hooks
macros to register the hooks in the Grafbase Gateway:
use grafbase_hooks::{ grafbase_hooks, register_hooks, Context, ErrorResponse, Headers, Hooks };
struct MyHooks;
#[grafbase_hooks]
impl Hooks for MyHooks {
fn new() -> Self
where
Self: Sized,
{
MyHooks
}
fn on_gateway_request(
&mut self,
context: Context,
headers: Headers
) -> Result<(), ErrorResponse> {
Ok(())
}
}
register_hooks!(MyHooks);
You can implement any of the default members from the Hooks
trait, and the gateway will call them at the appropriate time.
To compile the hooks, you need to install the wasm32-wasip2
target:
rustup target add wasm32-wasip2
Then build the hooks:
cargo build --release --target wasm32-wasip2
This will generate the WebAssembly component file target/wasm32-wasip2/release/my-hooks.wasm
. Copy the file to a place Grafbase Gateway can find it, and configure the gateway to use the hooks.
For a full example, and example use-cases for hooks, see our Implementing Gateway Hooks guide.
A hook call can block the host thread from processing other requests if the hook makes any IO. To avoid blocking the host thread, we created a host_io
module in the SDK. Currently, it has functions to execute HTTP requests and store data to the access logs.
This lets us define IO operations in the hooks without needing an async runtime in the guest; the IO works in a blocking way in the guest, but the host executes the IO in its async runtime and allows the request thread to yield to other requests.
We plan to add more functions to the host_io
module in the future, such as a TCP module which we can use as a base for libraries for connecting services like Memcached or Redis.
Eventually, with the next preview of WebAssembly System Interface, the guest will directly use the host's async runtime, and we will remove the host_io
module from the SDK. Meanwhile this gives you the needed building blocks to extend the Grafbase Gateway for your custom needs.