Upgrade axum crate from 0.6 to 0.7 version (#1224)

This commit is contained in:
Kai Ren 2023-11-27 14:14:02 +01:00 committed by GitHub
parent bd8dc582a4
commit 58ae682f91
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 63 additions and 60 deletions

View file

@ -10,7 +10,7 @@ All user visible changes to `juniper_axum` crate will be documented in this file
### Initialized ### Initialized
- Dependent on 0.6 version of [`axum` crate]. ([#1088]) - Dependent on 0.7 version of [`axum` crate]. ([#1088], [#1224])
- Dependent on 0.16 version of [`juniper` crate]. ([#1088]) - Dependent on 0.16 version of [`juniper` crate]. ([#1088])
- Dependent on 0.4 version of [`juniper_graphql_ws` crate]. ([#1088]) - Dependent on 0.4 version of [`juniper_graphql_ws` crate]. ([#1088])
@ -28,6 +28,7 @@ All user visible changes to `juniper_axum` crate will be documented in this file
[#986]: /../../issues/986 [#986]: /../../issues/986
[#1088]: /../../pull/1088 [#1088]: /../../pull/1088
[#1184]: /../../issues/1184 [#1184]: /../../issues/1184
[#1224]: /../../pull/1224

View file

@ -25,7 +25,7 @@ rustdoc-args = ["--cfg", "docsrs"]
subscriptions = ["axum/ws", "juniper_graphql_ws/graphql-ws", "dep:futures"] subscriptions = ["axum/ws", "juniper_graphql_ws/graphql-ws", "dep:futures"]
[dependencies] [dependencies]
axum = "0.6.20" axum = "0.7"
futures = { version = "0.3.22", optional = true } futures = { version = "0.3.22", optional = true }
juniper = { version = "0.16.0-dev", path = "../juniper", default-features = false } juniper = { version = "0.16.0-dev", path = "../juniper", default-features = false }
juniper_graphql_ws = { version = "0.4.0-dev", path = "../juniper_graphql_ws", features = ["graphql-transport-ws"] } juniper_graphql_ws = { version = "0.4.0-dev", path = "../juniper_graphql_ws", features = ["graphql-transport-ws"] }
@ -38,9 +38,10 @@ bytes = "1.2"
[dev-dependencies] [dev-dependencies]
anyhow = "1.0" anyhow = "1.0"
axum = { version = "0.6", features = ["macros"] } axum = { version = "0.7", features = ["http1", "macros", "tokio"] }
futures = "0.3.22"
juniper = { version = "0.16.0-dev", path = "../juniper", features = ["expose-test-schema"] } juniper = { version = "0.16.0-dev", path = "../juniper", features = ["expose-test-schema"] }
tokio = { version = "1.20", features = ["macros", "rt-multi-thread", "time"] } tokio = { version = "1.20", features = ["macros", "net", "rt-multi-thread", "time"] }
tokio-stream = "0.1" tokio-stream = "0.1"
tokio-tungstenite = "0.20" tokio-tungstenite = "0.20"
tower-service = "0.3" tower-service = "0.3"

View file

@ -19,6 +19,7 @@ use juniper_axum::{
extract::JuniperRequest, graphiql, playground, response::JuniperResponse, subscriptions, extract::JuniperRequest, graphiql, playground, response::JuniperResponse, subscriptions,
}; };
use juniper_graphql_ws::ConnectionConfig; use juniper_graphql_ws::ConnectionConfig;
use tokio::net::TcpListener;
type Schema = RootNode<'static, Query, EmptyMutation<Database>, Subscription>; type Schema = RootNode<'static, Query, EmptyMutation<Database>, Subscription>;
@ -68,7 +69,7 @@ async fn main() {
let app = Router::new() let app = Router::new()
.route( .route(
"/graphql", "/graphql",
on(MethodFilter::GET | MethodFilter::POST, custom_graphql), on(MethodFilter::GET.or(MethodFilter::POST), custom_graphql),
) )
.route("/subscriptions", get(custom_subscriptions)) .route("/subscriptions", get(custom_subscriptions))
.route("/graphiql", get(graphiql("/graphql", "/subscriptions"))) .route("/graphiql", get(graphiql("/graphql", "/subscriptions")))
@ -78,9 +79,11 @@ async fn main() {
.layer(Extension(database)); .layer(Extension(database));
let addr = SocketAddr::from(([127, 0, 0, 1], 8080)); let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
tracing::info!("listening on {addr}"); let listener = TcpListener::bind(addr)
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await .await
.unwrap_or_else(|e| panic!("failed to run `axum::Server`: {e}")); .unwrap_or_else(|e| panic!("failed to listen on {addr}: {e}"));
tracing::info!("listening on {addr}");
axum::serve(listener, app)
.await
.unwrap_or_else(|e| panic!("failed to run `axum::serve`: {e}"));
} }

View file

@ -11,7 +11,7 @@ use futures::stream::{BoxStream, StreamExt as _};
use juniper::{graphql_object, graphql_subscription, EmptyMutation, FieldError, RootNode}; use juniper::{graphql_object, graphql_subscription, EmptyMutation, FieldError, RootNode};
use juniper_axum::{graphiql, graphql, playground, ws}; use juniper_axum::{graphiql, graphql, playground, ws};
use juniper_graphql_ws::ConnectionConfig; use juniper_graphql_ws::ConnectionConfig;
use tokio::time::interval; use tokio::{net::TcpListener, time::interval};
use tokio_stream::wrappers::IntervalStream; use tokio_stream::wrappers::IntervalStream;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
@ -65,7 +65,7 @@ async fn main() {
.route( .route(
"/graphql", "/graphql",
on( on(
MethodFilter::GET | MethodFilter::POST, MethodFilter::GET.or(MethodFilter::POST),
graphql::<Arc<Schema>>, graphql::<Arc<Schema>>,
), ),
) )
@ -79,9 +79,11 @@ async fn main() {
.layer(Extension(Arc::new(schema))); .layer(Extension(Arc::new(schema)));
let addr = SocketAddr::from(([127, 0, 0, 1], 8080)); let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
tracing::info!("listening on {addr}"); let listener = TcpListener::bind(addr)
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await .await
.unwrap_or_else(|e| panic!("failed to run `axum::Server`: {e}")); .unwrap_or_else(|e| panic!("failed to listen on {addr}: {e}"));
tracing::info!("listening on {addr}");
axum::serve(listener, app)
.await
.unwrap_or_else(|e| panic!("failed to run `axum::serve`: {e}"));
} }

View file

@ -71,14 +71,14 @@ where
S: ScalarValue; S: ScalarValue;
#[async_trait] #[async_trait]
impl<S, State> FromRequest<State, Body> for JuniperRequest<S> impl<S, State> FromRequest<State> for JuniperRequest<S>
where where
S: ScalarValue, S: ScalarValue,
State: Sync, State: Sync,
Query<GetRequest>: FromRequestParts<State>, Query<GetRequest>: FromRequestParts<State>,
Json<GraphQLBatchRequest<S>>: FromRequest<State, Body>, Json<GraphQLBatchRequest<S>>: FromRequest<State>,
<Json<GraphQLBatchRequest<S>> as FromRequest<State, Body>>::Rejection: fmt::Display, <Json<GraphQLBatchRequest<S>> as FromRequest<State>>::Rejection: fmt::Display,
String: FromRequest<State, Body>, String: FromRequest<State>,
{ {
type Rejection = Response; type Rejection = Response;
@ -96,7 +96,9 @@ where
.into_response() .into_response()
})?; })?;
match (req.method(), content_type) { // TODO: Move into `match` expression directly once MSRV is bumped higher than 1.74.
let method = req.method();
match (method, content_type) {
(&Method::GET, _) => req (&Method::GET, _) => req
.extract_parts::<Query<GetRequest>>() .extract_parts::<Query<GetRequest>>()
.await .await
@ -180,13 +182,8 @@ impl<S: ScalarValue> TryFrom<GetRequest> for GraphQLRequest<S> {
#[cfg(test)] #[cfg(test)]
mod juniper_request_tests { mod juniper_request_tests {
use std::fmt; use axum::{body::Body, extract::FromRequest as _, http::Request};
use futures::TryStreamExt as _;
use axum::{
body::{Body, Bytes, HttpBody},
extract::FromRequest as _,
http::Request,
};
use juniper::{ use juniper::{
graphql_input_value, graphql_input_value,
http::{GraphQLBatchRequest, GraphQLRequest}, http::{GraphQLBatchRequest, GraphQLRequest},
@ -279,18 +276,15 @@ mod juniper_request_tests {
} }
} }
/// Converts the provided [`HttpBody`] into a [`String`]. /// Converts the provided [`Body`] into a [`String`].
async fn display_body<B>(mut body: B) -> String async fn display_body(body: Body) -> String {
where String::from_utf8(
B: HttpBody<Data = Bytes> + Unpin, body.into_data_stream()
B::Error: fmt::Display, .map_ok(|bytes| bytes.to_vec())
{ .try_concat()
let mut body_bytes = vec![]; .await
while let Some(bytes) = body.data().await { .unwrap(),
body_bytes.extend( )
bytes.unwrap_or_else(|e| panic!("failed to represent `Body` as `Bytes`: {e}")), .unwrap_or_else(|e| panic!("not UTF-8 body: {e}"))
);
}
String::from_utf8(body_bytes).unwrap_or_else(|e| panic!("not UTF-8 body: {e}"))
} }
} }

View file

@ -1,12 +1,13 @@
use std::sync::Arc; use std::sync::Arc;
use axum::{ use axum::{
body::{Body, HttpBody as _}, body::Body,
http::Request, http::Request,
response::Response, response::Response,
routing::{get, post}, routing::{get, post},
Extension, Router, Extension, Router,
}; };
use futures::TryStreamExt as _;
use juniper::{ use juniper::{
http::tests::{run_http_test_suite, HttpIntegration, TestResponse}, http::tests::{run_http_test_suite, HttpIntegration, TestResponse},
tests::fixtures::starwars::schema::{Database, Query}, tests::fixtures::starwars::schema::{Database, Query},
@ -97,12 +98,15 @@ async fn into_test_response(resp: Response) -> TestResponse {
}) })
.unwrap_or_default(); .unwrap_or_default();
let mut body = resp.into_body(); let body = String::from_utf8(
let mut body_bytes = vec![]; resp.into_body()
while let Some(bytes) = body.data().await { .into_data_stream()
body_bytes.extend(bytes.unwrap()); .map_ok(|bytes| bytes.to_vec())
} .try_concat()
let body = String::from_utf8(body_bytes).unwrap_or_else(|e| panic!("not UTF-8 body: {e}")); .await
.unwrap(),
)
.unwrap_or_else(|e| panic!("not UTF-8 body: {e}"));
TestResponse { TestResponse {
status_code, status_code,

View file

@ -1,9 +1,6 @@
#![cfg(not(windows))] #![cfg(not(windows))]
use std::{ use std::{net::SocketAddr, sync::Arc};
net::{SocketAddr, TcpListener},
sync::Arc,
};
use anyhow::anyhow; use anyhow::anyhow;
use axum::{routing::get, Extension, Router}; use axum::{routing::get, Extension, Router};
@ -15,7 +12,10 @@ use juniper::{
}; };
use juniper_axum::subscriptions; use juniper_axum::subscriptions;
use juniper_graphql_ws::ConnectionConfig; use juniper_graphql_ws::ConnectionConfig;
use tokio::{net::TcpStream, time::timeout}; use tokio::{
net::{TcpListener, TcpStream},
time::timeout,
};
use tokio_tungstenite::{connect_async, tungstenite::Message, MaybeTlsStream, WebSocketStream}; use tokio_tungstenite::{connect_async, tungstenite::Message, MaybeTlsStream, WebSocketStream};
type Schema = RootNode<'static, Query, EmptyMutation<Database>, Subscription>; type Schema = RootNode<'static, Query, EmptyMutation<Database>, Subscription>;
@ -49,15 +49,13 @@ impl TestApp {
} }
async fn run(self, messages: Vec<WsIntegrationMessage>) -> Result<(), anyhow::Error> { async fn run(self, messages: Vec<WsIntegrationMessage>) -> Result<(), anyhow::Error> {
let listener = TcpListener::bind("0.0.0.0:0".parse::<SocketAddr>().unwrap()).unwrap(); let listener = TcpListener::bind("0.0.0.0:0".parse::<SocketAddr>().unwrap())
.await
.unwrap();
let addr = listener.local_addr().unwrap(); let addr = listener.local_addr().unwrap();
tokio::spawn(async move { tokio::spawn(async move {
axum::Server::from_tcp(listener) axum::serve(listener, self.0).await.unwrap();
.unwrap()
.serve(self.0.into_make_service())
.await
.unwrap();
}); });
let (mut websocket, _) = connect_async(format!("ws://{}/subscriptions", addr)) let (mut websocket, _) = connect_async(format!("ws://{}/subscriptions", addr))

View file

@ -39,7 +39,7 @@ impl TestWarpIntegration {
let rt = tokio::runtime::Runtime::new() let rt = tokio::runtime::Runtime::new()
.unwrap_or_else(|e| panic!("failed to create `tokio::Runtime`: {e}")); .unwrap_or_else(|e| panic!("failed to create `tokio::Runtime`: {e}"));
rt.block_on(async move { rt.block_on(async move {
make_test_response(req.filter(&self.filter).await.unwrap_or_else(|rejection| { into_test_response(req.filter(&self.filter).await.unwrap_or_else(|rejection| {
let code = if rejection.is_not_found() { let code = if rejection.is_not_found() {
http::StatusCode::NOT_FOUND http::StatusCode::NOT_FOUND
} else if let Some(body::BodyDeserializeError { .. }) = rejection.find() { } else if let Some(body::BodyDeserializeError { .. }) = rejection.find() {
@ -101,7 +101,7 @@ impl HttpIntegration for TestWarpIntegration {
} }
} }
async fn make_test_response(resp: reply::Response) -> TestResponse { async fn into_test_response(resp: reply::Response) -> TestResponse {
let (parts, body) = resp.into_parts(); let (parts, body) = resp.into_parts();
let status_code = parts.status.as_u16().into(); let status_code = parts.status.as_u16().into();