Closed
Description
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");
}