Upgrade axum
crate from 0.6 to 0.7 version (#1224)
This commit is contained in:
parent
bd8dc582a4
commit
58ae682f91
8 changed files with 63 additions and 60 deletions
|
@ -10,7 +10,7 @@ All user visible changes to `juniper_axum` crate will be documented in this file
|
|||
|
||||
### 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.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
|
||||
[#1088]: /../../pull/1088
|
||||
[#1184]: /../../issues/1184
|
||||
[#1224]: /../../pull/1224
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ rustdoc-args = ["--cfg", "docsrs"]
|
|||
subscriptions = ["axum/ws", "juniper_graphql_ws/graphql-ws", "dep:futures"]
|
||||
|
||||
[dependencies]
|
||||
axum = "0.6.20"
|
||||
axum = "0.7"
|
||||
futures = { version = "0.3.22", optional = true }
|
||||
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"] }
|
||||
|
@ -38,9 +38,10 @@ bytes = "1.2"
|
|||
|
||||
[dev-dependencies]
|
||||
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"] }
|
||||
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-tungstenite = "0.20"
|
||||
tower-service = "0.3"
|
||||
|
|
|
@ -19,6 +19,7 @@ use juniper_axum::{
|
|||
extract::JuniperRequest, graphiql, playground, response::JuniperResponse, subscriptions,
|
||||
};
|
||||
use juniper_graphql_ws::ConnectionConfig;
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
type Schema = RootNode<'static, Query, EmptyMutation<Database>, Subscription>;
|
||||
|
||||
|
@ -68,7 +69,7 @@ async fn main() {
|
|||
let app = Router::new()
|
||||
.route(
|
||||
"/graphql",
|
||||
on(MethodFilter::GET | MethodFilter::POST, custom_graphql),
|
||||
on(MethodFilter::GET.or(MethodFilter::POST), custom_graphql),
|
||||
)
|
||||
.route("/subscriptions", get(custom_subscriptions))
|
||||
.route("/graphiql", get(graphiql("/graphql", "/subscriptions")))
|
||||
|
@ -78,9 +79,11 @@ async fn main() {
|
|||
.layer(Extension(database));
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
|
||||
tracing::info!("listening on {addr}");
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = TcpListener::bind(addr)
|
||||
.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}"));
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ use futures::stream::{BoxStream, StreamExt as _};
|
|||
use juniper::{graphql_object, graphql_subscription, EmptyMutation, FieldError, RootNode};
|
||||
use juniper_axum::{graphiql, graphql, playground, ws};
|
||||
use juniper_graphql_ws::ConnectionConfig;
|
||||
use tokio::time::interval;
|
||||
use tokio::{net::TcpListener, time::interval};
|
||||
use tokio_stream::wrappers::IntervalStream;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
@ -65,7 +65,7 @@ async fn main() {
|
|||
.route(
|
||||
"/graphql",
|
||||
on(
|
||||
MethodFilter::GET | MethodFilter::POST,
|
||||
MethodFilter::GET.or(MethodFilter::POST),
|
||||
graphql::<Arc<Schema>>,
|
||||
),
|
||||
)
|
||||
|
@ -79,9 +79,11 @@ async fn main() {
|
|||
.layer(Extension(Arc::new(schema)));
|
||||
|
||||
let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
|
||||
tracing::info!("listening on {addr}");
|
||||
axum::Server::bind(&addr)
|
||||
.serve(app.into_make_service())
|
||||
let listener = TcpListener::bind(addr)
|
||||
.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}"));
|
||||
}
|
||||
|
|
|
@ -71,14 +71,14 @@ where
|
|||
S: ScalarValue;
|
||||
|
||||
#[async_trait]
|
||||
impl<S, State> FromRequest<State, Body> for JuniperRequest<S>
|
||||
impl<S, State> FromRequest<State> for JuniperRequest<S>
|
||||
where
|
||||
S: ScalarValue,
|
||||
State: Sync,
|
||||
Query<GetRequest>: FromRequestParts<State>,
|
||||
Json<GraphQLBatchRequest<S>>: FromRequest<State, Body>,
|
||||
<Json<GraphQLBatchRequest<S>> as FromRequest<State, Body>>::Rejection: fmt::Display,
|
||||
String: FromRequest<State, Body>,
|
||||
Json<GraphQLBatchRequest<S>>: FromRequest<State>,
|
||||
<Json<GraphQLBatchRequest<S>> as FromRequest<State>>::Rejection: fmt::Display,
|
||||
String: FromRequest<State>,
|
||||
{
|
||||
type Rejection = Response;
|
||||
|
||||
|
@ -96,7 +96,9 @@ where
|
|||
.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
|
||||
.extract_parts::<Query<GetRequest>>()
|
||||
.await
|
||||
|
@ -180,13 +182,8 @@ impl<S: ScalarValue> TryFrom<GetRequest> for GraphQLRequest<S> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod juniper_request_tests {
|
||||
use std::fmt;
|
||||
|
||||
use axum::{
|
||||
body::{Body, Bytes, HttpBody},
|
||||
extract::FromRequest as _,
|
||||
http::Request,
|
||||
};
|
||||
use axum::{body::Body, extract::FromRequest as _, http::Request};
|
||||
use futures::TryStreamExt as _;
|
||||
use juniper::{
|
||||
graphql_input_value,
|
||||
http::{GraphQLBatchRequest, GraphQLRequest},
|
||||
|
@ -279,18 +276,15 @@ mod juniper_request_tests {
|
|||
}
|
||||
}
|
||||
|
||||
/// Converts the provided [`HttpBody`] into a [`String`].
|
||||
async fn display_body<B>(mut body: B) -> String
|
||||
where
|
||||
B: HttpBody<Data = Bytes> + Unpin,
|
||||
B::Error: fmt::Display,
|
||||
{
|
||||
let mut body_bytes = vec![];
|
||||
while let Some(bytes) = body.data().await {
|
||||
body_bytes.extend(
|
||||
bytes.unwrap_or_else(|e| panic!("failed to represent `Body` as `Bytes`: {e}")),
|
||||
);
|
||||
}
|
||||
String::from_utf8(body_bytes).unwrap_or_else(|e| panic!("not UTF-8 body: {e}"))
|
||||
/// Converts the provided [`Body`] into a [`String`].
|
||||
async fn display_body(body: Body) -> String {
|
||||
String::from_utf8(
|
||||
body.into_data_stream()
|
||||
.map_ok(|bytes| bytes.to_vec())
|
||||
.try_concat()
|
||||
.await
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap_or_else(|e| panic!("not UTF-8 body: {e}"))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use axum::{
|
||||
body::{Body, HttpBody as _},
|
||||
body::Body,
|
||||
http::Request,
|
||||
response::Response,
|
||||
routing::{get, post},
|
||||
Extension, Router,
|
||||
};
|
||||
use futures::TryStreamExt as _;
|
||||
use juniper::{
|
||||
http::tests::{run_http_test_suite, HttpIntegration, TestResponse},
|
||||
tests::fixtures::starwars::schema::{Database, Query},
|
||||
|
@ -97,12 +98,15 @@ async fn into_test_response(resp: Response) -> TestResponse {
|
|||
})
|
||||
.unwrap_or_default();
|
||||
|
||||
let mut body = resp.into_body();
|
||||
let mut body_bytes = vec![];
|
||||
while let Some(bytes) = body.data().await {
|
||||
body_bytes.extend(bytes.unwrap());
|
||||
}
|
||||
let body = String::from_utf8(body_bytes).unwrap_or_else(|e| panic!("not UTF-8 body: {e}"));
|
||||
let body = String::from_utf8(
|
||||
resp.into_body()
|
||||
.into_data_stream()
|
||||
.map_ok(|bytes| bytes.to_vec())
|
||||
.try_concat()
|
||||
.await
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap_or_else(|e| panic!("not UTF-8 body: {e}"));
|
||||
|
||||
TestResponse {
|
||||
status_code,
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
#![cfg(not(windows))]
|
||||
|
||||
use std::{
|
||||
net::{SocketAddr, TcpListener},
|
||||
sync::Arc,
|
||||
};
|
||||
use std::{net::SocketAddr, sync::Arc};
|
||||
|
||||
use anyhow::anyhow;
|
||||
use axum::{routing::get, Extension, Router};
|
||||
|
@ -15,7 +12,10 @@ use juniper::{
|
|||
};
|
||||
use juniper_axum::subscriptions;
|
||||
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};
|
||||
|
||||
type Schema = RootNode<'static, Query, EmptyMutation<Database>, Subscription>;
|
||||
|
@ -49,15 +49,13 @@ impl TestApp {
|
|||
}
|
||||
|
||||
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();
|
||||
|
||||
tokio::spawn(async move {
|
||||
axum::Server::from_tcp(listener)
|
||||
.unwrap()
|
||||
.serve(self.0.into_make_service())
|
||||
.await
|
||||
.unwrap();
|
||||
axum::serve(listener, self.0).await.unwrap();
|
||||
});
|
||||
|
||||
let (mut websocket, _) = connect_async(format!("ws://{}/subscriptions", addr))
|
||||
|
|
|
@ -39,7 +39,7 @@ impl TestWarpIntegration {
|
|||
let rt = tokio::runtime::Runtime::new()
|
||||
.unwrap_or_else(|e| panic!("failed to create `tokio::Runtime`: {e}"));
|
||||
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() {
|
||||
http::StatusCode::NOT_FOUND
|
||||
} 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 status_code = parts.status.as_u16().into();
|
||||
|
|
Loading…
Reference in a new issue