diff --git a/examples/actix_subscriptions/Cargo.toml b/examples/actix_subscriptions/Cargo.toml index 7685fc25..5c00aac1 100644 --- a/examples/actix_subscriptions/Cargo.toml +++ b/examples/actix_subscriptions/Cargo.toml @@ -6,8 +6,8 @@ authors = ["Mihai Dinculescu "] publish = false [dependencies] -actix-web = "4.0.0-beta.5" -actix-cors = "0.6.0-beta.1" +actix-web = "4.0.0-beta.8" +actix-cors = {git = "https://github.com/actix/actix-extras"} futures = "0.3" env_logger = "0.8" serde = "1.0" diff --git a/examples/actix_subscriptions/src/main.rs b/examples/actix_subscriptions/src/main.rs index b8945a54..6464a71e 100644 --- a/examples/actix_subscriptions/src/main.rs +++ b/examples/actix_subscriptions/src/main.rs @@ -1,7 +1,12 @@ use std::{env, pin::Pin, time::Duration}; use actix_cors::Cors; -use actix_web::{http::header, middleware, web, App, Error, HttpRequest, HttpResponse, HttpServer}; +use actix_web::{ + http::header, + middleware, + web::{self, Data}, + App, Error, HttpRequest, HttpResponse, HttpServer, +}; use juniper::{ graphql_object, graphql_subscription, @@ -114,18 +119,18 @@ async fn main() -> std::io::Result<()> { HttpServer::new(move || { App::new() - .data(schema()) - .wrap(middleware::Compress::default()) - .wrap(middleware::Logger::default()) + .app_data(Data::new(schema())) .wrap( Cors::default() - .allowed_origin("http://127.0.0.1:8080") + .allow_any_origin() .allowed_methods(vec!["POST", "GET"]) .allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT]) .allowed_header(header::CONTENT_TYPE) .supports_credentials() .max_age(3600), ) + .wrap(middleware::Compress::default()) + .wrap(middleware::Logger::default()) .service(web::resource("/subscriptions").route(web::get().to(subscriptions))) .service( web::resource("/graphql") diff --git a/juniper_actix/Cargo.toml b/juniper_actix/Cargo.toml index 73988f32..ac04e0ee 100644 --- a/juniper_actix/Cargo.toml +++ b/juniper_actix/Cargo.toml @@ -12,14 +12,11 @@ repository = "https://github.com/graphql-rust/juniper" subscriptions = ["juniper_graphql_ws"] [dependencies] -actix = "0.11" -# actix-web had some problems in beta release see https://github.com/actix/actix-web/issues/2173#issuecomment-822758353 -# and we need these version specification to handle this issue temporarily while the stable release is not available -# to understand these dependecy version specification see https://github.com/actix/actix-web/issues/2185 or https://github.com/LukeMathWalker/zero-to-production/issues/96 -actix-http = "=3.0.0-beta.5" -actix-service = "=2.0.0-beta.5" -actix-web = "=4.0.0-beta.5" -actix-web-actors = "4.0.0-beta.4" +actix = "0.12" +actix-http = "3.0.0-beta.8" +http = "0.2.4" +actix-web = "4.0.0-beta.8" +actix-web-actors = "4.0.0-beta.6" juniper = { version = "0.15.6", path = "../juniper", default-features = false } juniper_graphql_ws = { version = "0.2.5", path = "../juniper_graphql_ws", optional = true } @@ -32,11 +29,11 @@ thiserror = "1.0" [dev-dependencies] actix-rt = "2" -actix-cors = "0.6.0-beta.1" -actix-identity = "0.4.0-beta.1" +actix-cors = {git = "https://github.com/actix/actix-extras"} +actix-identity = {git = "https://github.com/actix/actix-extras"} tokio = "1" async-stream = "0.3" -actix-test = "0.1.0-beta.1" +actix-test = "0.1.0-beta.3" juniper = { version = "0.15.6", path = "../juniper", features = ["expose-test-schema"] } diff --git a/juniper_actix/examples/actix_server.rs b/juniper_actix/examples/actix_server.rs index 982313a5..7a963807 100644 --- a/juniper_actix/examples/actix_server.rs +++ b/juniper_actix/examples/actix_server.rs @@ -3,7 +3,12 @@ use std::{collections::HashMap, env}; use actix_cors::Cors; -use actix_web::{http::header, middleware, web, App, Error, HttpResponse, HttpServer}; +use actix_web::{ + http::header, + middleware, + web::{self, Data}, + App, Error, HttpResponse, HttpServer, +}; use juniper::{graphql_object, EmptyMutation, EmptySubscription, GraphQLObject, RootNode}; use juniper_actix::{graphiql_handler, graphql_handler, playground_handler}; @@ -107,18 +112,18 @@ async fn main() -> std::io::Result<()> { let server = HttpServer::new(move || { App::new() - .data(schema()) - .wrap(middleware::Compress::default()) - .wrap(middleware::Logger::default()) + .app_data(Data::new(schema())) .wrap( Cors::default() - .allowed_origin("http://127.0.0.1:8080") + .allow_any_origin() .allowed_methods(vec!["POST", "GET"]) .allowed_headers(vec![header::AUTHORIZATION, header::ACCEPT]) .allowed_header(header::CONTENT_TYPE) .supports_credentials() .max_age(3600), ) + .wrap(middleware::Compress::default()) + .wrap(middleware::Logger::default()) .service( web::resource("/graphgl") .route(web::post().to(graphql_route)) diff --git a/juniper_actix/src/lib.rs b/juniper_actix/src/lib.rs index 315632a5..212c2438 100644 --- a/juniper_actix/src/lib.rs +++ b/juniper_actix/src/lib.rs @@ -41,9 +41,8 @@ Check the LICENSE file for details. #![doc(html_root_url = "https://docs.rs/juniper_actix/0.1.0")] use actix_web::{ - error::{ErrorBadRequest, ErrorMethodNotAllowed, ErrorUnsupportedMediaType}, - http::Method, - web, Error, FromRequest, HttpMessage, HttpRequest, HttpResponse, + error::JsonPayloadError, http::Method, web, Error, FromRequest, HttpMessage, HttpRequest, + HttpResponse, }; use juniper::{ http::{ @@ -98,9 +97,7 @@ where match *req.method() { Method::POST => post_graphql_handler(schema, context, req, payload).await, Method::GET => get_graphql_handler(schema, context, req).await, - _ => Err(ErrorMethodNotAllowed( - "GraphQL requests can only be sent with GET or POST", - )), + _ => Err(actix_web::error::UrlGenerationError::ResourceNotFound.into()), } } /// Actix GraphQL Handler for GET requests @@ -152,7 +149,8 @@ where let req = match req.content_type() { "application/json" => { let body = String::from_request(&req, &mut payload.into_inner()).await?; - serde_json::from_str::>(&body).map_err(ErrorBadRequest) + serde_json::from_str::>(&body) + .map_err(JsonPayloadError::Deserialize) } "application/graphql" => { let body = String::from_request(&req, &mut payload.into_inner()).await?; @@ -160,9 +158,7 @@ where body, None, None, ))) } - _ => Err(ErrorUnsupportedMediaType( - "GraphQL requests should have content type `application/json` or `application/graphql`", - )), + _ => Err(JsonPayloadError::ContentType), }?; let gql_batch_response = req.execute(schema, context).await; let gql_response = serde_json::to_string(&gql_batch_response)?; @@ -472,9 +468,9 @@ pub mod subscriptions { #[cfg(test)] mod tests { - use actix_web::{dev::ServiceResponse, http, http::header::CONTENT_TYPE, test, App}; + use actix_http::body::AnyBody; + use actix_web::{dev::ServiceResponse, http, http::header::CONTENT_TYPE, test, web::Data, App}; use juniper::{ - futures::stream::StreamExt, http::tests::{run_http_test_suite, HttpIntegration, TestResponse}, tests::fixtures::starwars::schema::{Database, Query}, EmptyMutation, EmptySubscription, RootNode, @@ -487,14 +483,9 @@ mod tests { juniper::RootNode<'static, Query, EmptyMutation, EmptySubscription>; async fn take_response_body_string(resp: &mut ServiceResponse) -> String { - let (response_body, ..) = resp - .take_body() - .map(|body_out| body_out.unwrap().to_vec()) - .into_future() - .await; - match response_body { - Some(response_body) => String::from_utf8(response_body).unwrap(), - None => String::from(""), + match resp.response().body() { + AnyBody::Bytes(body) => String::from_utf8(body.to_vec()).unwrap(), + _ => String::from(""), } } @@ -608,11 +599,15 @@ mod tests { .uri("/") .to_request(); - let mut app = - test::init_service(App::new().data(schema).route("/", web::post().to(index))).await; + let mut app = test::init_service( + App::new() + .app_data(Data::new(schema)) + .route("/", web::post().to(index)), + ) + .await; let mut resp = test::call_service(&mut app, req).await; - + dbg!(take_response_body_string(&mut resp).await); assert_eq!(resp.status(), http::StatusCode::OK); assert_eq!( take_response_body_string(&mut resp).await, @@ -637,8 +632,12 @@ mod tests { .uri("/?query=%7B%20hero%28episode%3A%20NEW_HOPE%29%20%7B%20name%20%7D%20%7D&variables=null") .to_request(); - let mut app = - test::init_service(App::new().data(schema).route("/", web::get().to(index))).await; + let mut app = test::init_service( + App::new() + .app_data(Data::new(schema)) + .route("/", web::get().to(index)), + ) + .await; let mut resp = test::call_service(&mut app, req).await; @@ -677,8 +676,12 @@ mod tests { .uri("/") .to_request(); - let mut app = - test::init_service(App::new().data(schema).route("/", web::post().to(index))).await; + let mut app = test::init_service( + App::new() + .app_data(Data::new(schema)) + .route("/", web::post().to(index)), + ) + .await; let mut resp = test::call_service(&mut app, req).await; @@ -712,8 +715,12 @@ mod tests { EmptySubscription::::new(), ); - let mut app = - test::init_service(App::new().data(schema).route("/", web::to(index))).await; + let mut app = test::init_service( + App::new() + .app_data(Data::new(schema)) + .route("/", web::to(index)), + ) + .await; let resp = test::call_service(&mut app, req.to_request()).await; make_test_response(resp).await @@ -768,7 +775,10 @@ mod subscription_tests { use std::time::Duration; use actix_test::start; - use actix_web::{web, App, Error, HttpRequest, HttpResponse}; + use actix_web::{ + web::{self, Data}, + App, Error, HttpRequest, HttpResponse, + }; use actix_web_actors::ws; use juniper::{ futures::{SinkExt, StreamExt}, @@ -791,11 +801,11 @@ mod subscription_tests { ) -> Result<(), anyhow::Error> { let mut server = start(|| { App::new() - .data(Schema::new( + .app_data(Data::new(Schema::new( Query, EmptyMutation::::new(), Subscription, - )) + ))) .service(web::resource("/subscriptions").to(subscriptions)) }); let mut framed = server.ws_at("/subscriptions").await.unwrap();