Repository: graphql-rust/juniper (language: rust)

Issue:
JuniperRequest and Response are not seen as implementors of axum 0.8.x Extractors
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.

```rust
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
```


Discussion / hints:

Fix patch:
diff --git a/juniper_axum/CHANGELOG.md b/juniper_axum/CHANGELOG.md
index 8b74ffbb7..03d1520b0 100644
--- a/juniper_axum/CHANGELOG.md
+++ b/juniper_axum/CHANGELOG.md
@@ -11,6 +11,7 @@ All user visible changes to `juniper_axum` crate will be documented in this file
 ### BC Breaks
 
 - Bumped up [MSRV] to 1.75. ([#1272])
+- Upgraded to 0.8 version of [`axum` crate]. ([#1303], [#1306])
 
 ### Added
 
@@ -19,6 +20,8 @@ All user visible changes to `juniper_axum` crate will be documented in this file
 [#1272]: /../../pull/1272
 [#1282]: /../../issues/1282
 [#1283]: /../../pull/1283
+[#1303]: /../../pull/1303
+[#1306]: /../../pull/1306
 
 
 
diff --git a/juniper_axum/Cargo.toml b/juniper_axum/Cargo.toml
index 0b664775c..ae36d08bd 100644
--- a/juniper_axum/Cargo.toml
+++ b/juniper_axum/Cargo.toml
@@ -25,7 +25,7 @@ rustdoc-args = ["--cfg", "docsrs"]
 subscriptions = ["axum/ws", "juniper_graphql_ws/graphql-ws", "dep:futures"]
 
 [dependencies]
-axum = { version = "0.7", features = ["json", "query"], default-features = false }
+axum = { version = "0.8", features = ["json", "query"], default-features = false }
 futures = { version = "0.3.22", optional = true }
 juniper = { version = "0.16", path = "../juniper", default-features = false }
 juniper_graphql_ws = { version = "0.4.0", path = "../juniper_graphql_ws", features = ["graphql-transport-ws"] }
@@ -38,7 +38,7 @@ bytes = "1.2"
 
 [dev-dependencies]
 anyhow = "1.0"
-axum = { version = "0.7", features = ["http1", "macros", "tokio"] }
+axum = { version = "0.8.1", features = ["http1", "macros", "tokio"] }
 futures = "0.3.22"
 juniper = { version = "0.16", path = "../juniper", features = ["expose-test-schema"] }
 tokio = { version = "1.20", features = ["macros", "net", "rt-multi-thread", "time"] }
diff --git a/juniper_axum/src/extract.rs b/juniper_axum/src/extract.rs
index 1029d05e0..c8caec708 100644
--- a/juniper_axum/src/extract.rs
+++ b/juniper_axum/src/extract.rs
@@ -3,7 +3,6 @@
 use std::fmt;
 
 use axum::{
-    async_trait,
     body::Body,
     extract::{FromRequest, FromRequestParts, Query},
     http::{header, HeaderValue, Method, Request, StatusCode},
@@ -70,7 +69,6 @@ pub struct JuniperRequest<S = DefaultScalarValue>(pub GraphQLBatchRequest<S>)
 where
     S: ScalarValue;
 
-#[async_trait]
 impl<S, State> FromRequest<State> for JuniperRequest<S>
 where
     S: ScalarValue,
diff --git a/juniper_axum/src/subscriptions.rs b/juniper_axum/src/subscriptions.rs
index cc1ec7d70..9ca12b8bd 100644
--- a/juniper_axum/src/subscriptions.rs
+++ b/juniper_axum/src/subscriptions.rs
@@ -488,7 +488,7 @@ where
             Ok(match output {
                 graphql_transport_ws::Output::Message(msg) => {
                     serde_json::to_string(&msg)
-                        .map(ws::Message::Text)
+                        .map(ws::Message::text)
                         .unwrap_or_else(|e| {
                             ws::Message::Close(Some(ws::CloseFrame {
                                 code: 1011, // CloseCode::Error
@@ -618,7 +618,7 @@ where
     let output = s_rx
         .map(|msg| {
             Ok(serde_json::to_string(&msg)
-                .map(ws::Message::Text)
+                .map(ws::Message::text)
                 .unwrap_or_else(|e| {
                     ws::Message::Close(Some(ws::CloseFrame {
                         code: 1011, // CloseCode::Error


Test patch:
diff --git a/juniper_axum/tests/ws_test_suite.rs b/juniper_axum/tests/ws_test_suite.rs
index f60f671e1..92d7de1ca 100644
--- a/juniper_axum/tests/ws_test_suite.rs
+++ b/juniper_axum/tests/ws_test_suite.rs
@@ -88,7 +88,7 @@ impl TestApp {
                     None => Err(anyhow!("No message received")),
                     Some(Err(e)) => Err(anyhow!("WebSocket error: {e}")),
                     Some(Ok(Message::Text(json))) => {
-                        let actual: serde_json::Value = serde_json::from_str(&*json)
+                        let actual: serde_json::Value = serde_json::from_str(&json)
                             .map_err(|e| anyhow!("Cannot deserialize received message: {e}"))?;
                         if actual != expected {
                             return Err(anyhow!(