Skip to content

JuniperRequest and Response are not seen as implementors of axum 0.8.x Extractors #1305

@jonasrichard

Description

@jonasrichard

I hate to write things like this because it should work, but I don't have any idea why it says that JuniperRequest doesn't implement FromRequest even if it is a last param of the axum handler, and the similar issue with JuniperResponse. I am using everything up to date in Cargo.toml, but I can paste here, too.

use axum::{debug_handler, routing::post, Extension, Router};
use juniper::{
    graphql_object, EmptyMutation, EmptySubscription, RootNode,
};
use juniper_axum::{extract::JuniperRequest, response::JuniperResponse};
use std::{net::SocketAddr, sync::Arc};
use tokio::net::TcpListener;

#[derive(Clone, Copy, Debug, Default)]
pub struct Context;

#[derive(Clone, Copy, Debug)]
pub struct Query;

#[graphql_object(context = Context)]
impl Query {
    fn add(a: i32, b: i32) -> i32 {
        a + b
    }
}
type Schema = RootNode<'static, Query, EmptyMutation<Context>, EmptySubscription<Context>>;

#[debug_handler]
async fn graphql_handler(
    Extension(schema): Extension<Arc<Schema>>,
    Extension(context): Extension<Context>,
    JuniperRequest(req): JuniperRequest,
) -> JuniperResponse {
    req.execute(schema, todo!()).await
}

#[tokio::main]
async fn main() {
    let schema = Schema::new(
        Query,
        EmptyMutation::<Context>::new(),
        EmptySubscription::<Context>::new(),
    );

    let app = Router::new()
        .route("/graphql", post(graphql_handler))
        .layer(Extension(Arc::new(schema)))
        .layer(Extension(Context));

    let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
    let listener = TcpListener::bind(addr)
        .await
        .unwrap_or_else(|e| panic!("failed to listen on {addr}: {e}"));

    axum::serve(listener, app)
        .await
        .unwrap_or_else(|e| panic!("failed to serve: {e}"));
}

Error is:

error[E0308]: mismatched types
   --> src/main.rs:41:17
    |
41  |     req.execute(schema, todo!()).await
    |         ------- ^^^^^^ expected `&RootNode<'_, _, _, _>`, found `Arc<RootNode<'_, Query, ..., ...>>`
    |         |
    |         arguments to this method are incorrect
    |
    = note: expected reference `&RootNode<'_, _, _, _, _>`
                  found struct `Arc<RootNode<'_, Query, EmptyMutation<Context>, EmptySubscription<Context>, _>>`
note: method defined here
   --> /Users/richard.jonas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/juniper-0.16.1/src/http/mod.rs:297:18
    |
297 |     pub async fn execute<'a, QueryT, MutationT, SubscriptionT>(
    |                  ^^^^^^^
help: consider borrowing here
    |
41  |     req.execute(&schema, todo!()).await
    |                 +

warning: unreachable call
  --> src/main.rs:41:9
   |
41 |     req.execute(schema, todo!()).await
   |         ^^^^^^^         ------- any code following this expression is unreachable
   |         |
   |         unreachable call
   |
   = note: `#[warn(unreachable_code)]` on by default

error[E0308]: mismatched types
  --> src/main.rs:41:5
   |
41 |     req.execute(schema, todo!()).await
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `JuniperResponse`, found `GraphQLBatchResponse`
   |
   = note: expected struct `JuniperResponse`
                found enum `GraphQLBatchResponse`
help: try wrapping the expression in `juniper_axum::response::JuniperResponse`
   |
41 |     juniper_axum::response::JuniperResponse(req.execute(schema, todo!()).await)
   |     ++++++++++++++++++++++++++++++++++++++++                                  +

error[E0277]: the trait bound `JuniperResponse: IntoResponse` is not satisfied
  --> src/main.rs:40:6
   |
40 | ) -> JuniperResponse {
   |      ^^^^^^^^^^^^^^^ the trait `IntoResponse` is not implemented for `JuniperResponse`
   |
   = help: the following other types implement trait `IntoResponse`:
             &'static [u8; N]
             &'static [u8]
             &'static str
             ()
             (R,)
             (Response<()>, R)
             (Response<()>, T1, R)
             (Response<()>, T1, T2, R)
           and 120 others
note: required by a bound in `__axum_macros_check_graphql_handler_into_response::{closure#0}::check`
  --> src/main.rs:40:6
   |
40 | ) -> JuniperResponse {
   |      ^^^^^^^^^^^^^^^ required by this bound in `check`

error[E0308]: mismatched types
   --> src/main.rs:41:17
    |
41  |     req.execute(schema, todo!()).await
    |         ------- ^^^^^^ expected `&RootNode<'_, _, _, _>`, found `Arc<RootNode<'_, Query, ..., ...>>`
    |         |
    |         arguments to this method are incorrect
    |
    = note: expected reference `&RootNode<'_, _, _, _, _>`
                  found struct `Arc<RootNode<'static, Query, EmptyMutation<Context>, EmptySubscription<Context>, _>>`
note: method defined here
   --> /Users/richard.jonas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/juniper-0.16.1/src/http/mod.rs:297:18
    |
297 |     pub async fn execute<'a, QueryT, MutationT, SubscriptionT>(
    |                  ^^^^^^^
help: consider borrowing here
    |
41  |     req.execute(&schema, todo!()).await
    |                 +

error[E0277]: the trait bound `JuniperRequest: FromRequest<(), axum_core::extract::private::ViaParts>` is not satisfied
  --> src/main.rs:39:26
   |
39 |     JuniperRequest(req): JuniperRequest,
   |                          ^^^^^^^^^^^^^^ the trait `FromRequestParts<()>` is not implemented for `JuniperRequest`, which is required by `JuniperRequest: FromRequest<(), _>`
   |
   = note: Function argument is not a valid axum extractor. 
           See `https://docs.rs/axum/0.8/axum/extract/index.html` for details
   = help: the following other types implement trait `FromRequestParts<S>`:
             `()` implements `FromRequestParts<S>`
             `(T1, T2)` implements `FromRequestParts<S>`
             `(T1, T2, T3)` implements `FromRequestParts<S>`
             `(T1, T2, T3, T4)` implements `FromRequestParts<S>`
             `(T1, T2, T3, T4, T5)` implements `FromRequestParts<S>`
             `(T1, T2, T3, T4, T5, T6)` implements `FromRequestParts<S>`
             `(T1, T2, T3, T4, T5, T6, T7)` implements `FromRequestParts<S>`
             `(T1, T2, T3, T4, T5, T6, T7, T8)` implements `FromRequestParts<S>`
           and 27 others
   = note: required for `JuniperRequest` to implement `FromRequest<(), axum_core::extract::private::ViaParts>`
note: required by a bound in `__axum_macros_check_graphql_handler_2_from_request_check`
  --> src/main.rs:39:26
   |
39 |     JuniperRequest(req): JuniperRequest,
   |                          ^^^^^^^^^^^^^^ required by this bound in `__axum_macros_check_graphql_handler_2_from_request_check`

error[E0277]: the trait bound `fn(Extension<Arc<RootNode<'static, Query, EmptyMutation<Context>, EmptySubscription<Context>>>>, Extension<Context>, JuniperRequest) -> impl std::future::Future<Output = JuniperResponse> {graphql_handler}: Handler<_, _>` is not satisfied
   --> src/main.rs:53:33
    |
53  |         .route("/graphql", post(graphql_handler))
    |                            ---- ^^^^^^^^^^^^^^^ the trait `Handler<_, _>` is not implemented for fn item `fn(Extension<Arc<RootNode<'static, Query, EmptyMutation<Context>, EmptySubscription<Context>>>>, Extension<Context>, JuniperRequest) -> ... {graphql_handler}`
    |                            |
    |                            required by a bound introduced by this call
    |
    = note: the full name for the type has been written to '/Users/richard.jonas/projects/try-new-things/rust-offer-graphql/target/debug/deps/rust_offer_graphql-6f31c9da0ab7a774.long-type-10051857777317374710.txt'
    = note: consider using `--verbose` to print the full type name to the console
    = note: Consider using `#[axum::debug_handler]` to improve the error message
    = help: the following other types implement trait `Handler<T, S>`:
              `Layered<L, H, T, S>` implements `Handler<T, S>`
              `MethodRouter<S>` implements `Handler<(), S>`
note: required by a bound in `post`
   --> /Users/richard.jonas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/axum-0.8.1/src/routing/method_routing.rs:444:1
    |
444 | top_level_handler_fn!(post, POST);
    | ^^^^^^^^^^^^^^^^^^^^^^----^^^^^^^
    | |                     |
    | |                     required by a bound in this function
    | required by this bound in `post`
    = note: this error originates in the macro `top_level_handler_fn` (in Nightly builds, run with -Z macro-backtrace for more info)

Some errors have detailed explanations: E0277, E0308.
For more information about an error, try `rustc --explain E0277`.
warning: `rust-offer-graphql` (bin "rust-offer-graphql") generated 1 warning
error: could not compile `rust-offer-graphql` (bin "rust-offer-graphql") due to 9 previous errors; 1 warning emitted

Metadata

Metadata

Assignees

Labels

k::integrationRelated to integration with third-party libraries or systemslib::axumRelated to `axum` crate integrationsupport

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions