Actix v4.0.0-beta.8 support (#952)

This commit is contained in:
Jordão Rodrigues Oliveira Rosario 2021-07-06 19:41:42 -03:00 committed by GitHub
parent 739cc3bfc2
commit 6ada6b09a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 72 additions and 55 deletions

View file

@ -6,8 +6,8 @@ authors = ["Mihai Dinculescu <mihai.dinculescu@outlook.com>"]
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"

View file

@ -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")

View file

@ -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"] }

View file

@ -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))

View file

@ -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::<GraphQLBatchRequest<S>>(&body).map_err(ErrorBadRequest)
serde_json::from_str::<GraphQLBatchRequest<S>>(&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<Database>, EmptySubscription<Database>>;
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::<Database>::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::<Database>::new(),
Subscription,
))
)))
.service(web::resource("/subscriptions").to(subscriptions))
});
let mut framed = server.ws_at("/subscriptions").await.unwrap();