Integrating GraphQL with Rust using the async-graphql and axum libraries

Hi team,
I am trying to use graphql with Rust, but facing one small problem

While i am trying to inject my service into my schema builder, and later trying to fetch it from context inside resolvers i am getting error that no such service exist in the context passed

 // main.rs
use crate::routes::graphql::{graphql_handler, graphql_playground};
 
 let client = Arc::new(Client::new());
    let pokemon_service = Arc::new(PokemonService { client });
    let schema: Schema<QueryRoot, EmptyMutation, EmptySubscription> = Schema::build(QueryRoot, EmptyMutation, EmptySubscription)
    .data(pokemon_service.clone()) // Add PokemonService
    .finish();
let router = Router::new()
    .route("/graphql", get(graphql_playground)
    .post(graphql_handler))
    .layer(Extension(schema))
    .layer(Extension(pokemon_service.clone()));
// PokemonService.rs
use crate::routes::{evolution::EvolutionFlow, pokemons::Pokemon, species::EvolutionSpecies};
use axum::{extract::Query, Extension, Json};
use reqwest::{Client, StatusCode};
use std::{collections::HashMap, sync::Arc};
 
use super::api_caller::{call_api, CallType};
 
#[derive(Clone,Debug)]
pub struct PokemonService {
    pub client: Arc<Client>,
}
 
impl PokemonService { // some async functions 
}

// QueryRoot.rs
use async_graphql::{Context, Object};
 
use crate::{
    external::pokemon_api::PokemonService,
    routes::{
        evolution::EvolutionFlow, health::Health, pokemons::Pokemon, species::EvolutionSpecies,
    },
};
 
pub(crate) struct QueryRoot;
 
#[Object]
impl QueryRoot {
    async fn hello(&self, _ctx: &Context<'_>) -> &'static str {
        "Hello world"
    }
 
    async fn pokemon(&self, ctx: &Context<'_>, name: String) -> Pokemon {
        println!("{}: -<POKEMON", name);
// ALWAYS GOING TO ERROR HERE
        match ctx.data::<PokemonService>(){
            Ok(pokemon_service) => {
                println!("POKEMON SERVICE: {:?}", pokemon_service);
            },
            Err(_) => {
                println!("POKEMON SERVICE: None");
            }
        };
        Pokemon::no_pokemon()
    }

Whenever i am executing this, i am getting on Err(_) println!("POKEMON SERVICE: None");

Repo link for reff

I took the liberty and abbreviated your title a bit :sweat_smile:


Try extracting Arc<PokemonService> instead of PokemonService, which is the type you are registering here:

2 Likes

OMG, it worked. Can't believe i was overlooking such a small thing. Thanks a lot @jofas

1 Like