Skip to content

sharing request data with the resolvers with the FromRequest trait #1012

Closed
@folivi

Description

@folivi

Hi all,

can anyone help get my head around the FromRequest trait.

As I understand, we can use it to share data with the resolvers.

I'm trying to inject the http headers so I can authenticate users before some actions in the resolvers.

See my code below.

Looks like the from_request isn't even called.

I'm using rocket 0.5.rc1

Thank you for your help

use juniper::{graphql_object, EmptySubscription, RootNode};
use mongodb::Client;
use mongodb::Database;


use rocket::{catch, catchers};
use rocket::{response::content, Rocket, State};

type Schema = RootNode<'static, Query, Mutations, EmptySubscription<AppContext>>;

use rocket::{
    http::Status,
    request::{FromRequest, Outcome},
    Request,
};

struct Mutations;
struct Query;

#[derive(Debug)]
pub struct AppContext {
    pub mongodb_pool: Database,
    pub user: String,
}

impl juniper::Context for AppContext {}

#[rocket::async_trait]
impl<'r> FromRequest<'r> for AppContext {
    type Error = ();

    async fn from_request(request: &'r Request<'_>) -> Outcome<AppContext, Self::Error> {
        let client = Client::with_uri_str("mongodb://admin:admin@localhost:28017").await;
        let db = client.unwrap().database("override");
        Outcome::Success(AppContext { mongodb_pool: db, user: "from request".to_string() }, )
    }
}

#[graphql_object(context = AppContext)]
impl Query {
    fn api_version(db: &AppContext) -> &str {
        println!("{:?}", db.user);
        "1.0"
    }
}

#[graphql_object(context = AppContext)]
impl Mutations {
    fn api_version(db: &AppContext) -> String {
        "1.0".to_string()
    }
}

#[rocket::get("/")]
fn graphiql() -> content::Html<String> {
    juniper_rocket::graphiql_source("/graphql", None)
}

#[rocket::get("/graphql?<request>")]
async fn get_graphql_handler(
    context: &State<AppContext>,
    request: juniper_rocket::GraphQLRequest,
    schema: &State<Schema>,
) -> juniper_rocket::GraphQLResponse {
    request.execute(&*schema, &*context).await
}

#[rocket::post("/graphql", data = "<request>")]
async fn post_graphql_handler(
    context: &State<AppContext>,
    request: juniper_rocket::GraphQLRequest,
    schema: &State<Schema>,
) -> juniper_rocket::GraphQLResponse {
    request.execute(&*schema, &*context).await
}

#[tokio::main]
async fn main() {
    let client = Client::with_uri_str("mongodb://admin:admin@localhost:28017").await;
    let db = client.unwrap().database("app_db");

    Rocket::build()
        .manage(AppContext{ mongodb_pool: db, user: "from build".to_string() })
        .manage(Schema::new(
            Query,
            Mutations,
            EmptySubscription::<AppContext>::new(),
        ))
        .mount(
            "/",
            rocket::routes![graphiql, get_graphql_handler, post_graphql_handler],
        )
        .launch()
        .await
        .expect("server failed to launch");
}

Metadata

Metadata

Assignees

Labels

k::integrationRelated to integration with third-party libraries or systemslib::rocketRelated to `rocket` crate integrationsupport

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions