Skip to main content

πŸ•ΈοΈ GraphQL API Integration

GraphQL allows frontend clients to request precisely the data fields they need, reducing over-fetching and network payload sizes.

Ferrox provides ferrox-graphql, integrating Async-GraphQL with Axum.


1. Building a GraphQL Schema​

Define GraphQL query objects using async_graphql:

use async_graphql::{Object, Schema, EmptyMutation, EmptySubscription};

pub struct QueryRoot;

#[Object]
impl QueryRoot {
/// Returns application health ping
async fn ping(&self) -> &'static str {
"pong"
}

/// Returns a list of products
async fn products(&self) -> Vec<ProductGql> {
vec![
ProductGql { id: 1, name: "Ferrox Pro".into() }
]
}
}

pub struct ProductGql {
pub id: u64,
pub name: String,
}

#[Object]
impl ProductGql {
async fn id(&self) -> u64 { self.id }
async fn name(&self) -> &str { &self.name }
}

pub fn create_schema() -> Schema<QueryRoot, EmptyMutation, EmptySubscription> {
Schema::build(QueryRoot, EmptyMutation, EmptySubscription).finish()
}

2. Axum GraphQL Route Handler​

use async_graphql::http::{playground_source, GraphQLPlaygroundConfig};
use async_graphql_axum::{GraphQLRequest, GraphQLResponse};
use axum::{
extract::State,
response::{Html, IntoResponse},
routing::get,
Router,
};
use std::sync::Arc;

pub async fn graphql_handler(
State(schema): State<AppSchema>,
req: GraphQLRequest,
) -> GraphQLResponse {
schema.execute(req.into_inner()).await.into()
}

pub async fn graphql_playground() -> impl IntoResponse {
Html(playground_source(GraphQLPlaygroundConfig::new("/graphql")))
}

pub fn graphql_router(schema: AppSchema) -> Router {
Router::new()
.route("/graphql", get(graphql_playground).post(graphql_handler))
.with_state(schema)
}

3. Exporting GraphQL SDL for Frontend Code Generation​

ferrox-graphql includes helper utilities to export your schema in Schema Definition Language (SDL) format during build phase:

use ferrox_graphql::export_sdl;

let schema = create_schema();
export_sdl(&schema, "./schema.graphql")?;
// Generates schema.graphql for GraphQL Code Generator in React/Vue/Angular

4. Testing GraphQL Queries​

#[tokio::test]
async fn test_ping_query() {
let schema = create_schema();
let response = schema.execute("{ ping }").await;
assert_eq!(response.data.into_json().unwrap()["ping"], "pong");
}