Update juniper_rocket for Rocket 0.4 (#277)

Path handling changed in Rocket 0.4 and this commit updates the way
those paths are handled. It adds an implementation of the
`FromFormValue` trait to the `GraphQLRequest` object. It also changes
the documentation to use the multi-segment query string syntax.

All existing tests pass as expected.
This commit is contained in:
Eric Dattore 2018-12-10 17:45:22 -07:00 committed by Christian Legnitto
parent 3ce3b21eb1
commit cb00a7b2bc
4 changed files with 45 additions and 25 deletions

View file

@ -1,5 +1,14 @@
# [master] # [master]
### Rocket updated to v0.4
[Rocket](https://rocket.rs) integration now requires Rocket `0.4.0`. This is due
to changes with the way Rocket handles form parsing. Before this update, it was
impossible to leverage Rocket integration with Rocket beyond 0.3.x.
Check out [Rocket's Changelog](https://github.com/SergioBenitez/Rocket/blob/v0.4/CHANGELOG.md)
for more details on the 0.4 release.
# juniper_rocket [0.1.3] 2018-09-13 # juniper_rocket [0.1.3] 2018-09-13
- Add `juniper-0.10.0` compatibility. - Add `juniper-0.10.0` compatibility.

View file

@ -16,8 +16,7 @@ serde_json = { version = "1.0.2" }
serde_derive = { version = "1.0.2" } serde_derive = { version = "1.0.2" }
juniper = { version = ">=0.9, 0.10.0" , default-features = false, path = "../juniper"} juniper = { version = ">=0.9, 0.10.0" , default-features = false, path = "../juniper"}
rocket = { version = "0.3.9" } rocket = { version = "0.4.0" }
rocket_codegen = { version = "0.3.9" }
[dev-dependencies.juniper] [dev-dependencies.juniper]
version = "0.10.0" version = "0.10.0"

View file

@ -1,9 +1,8 @@
#![feature(plugin)] #![feature(decl_macro, proc_macro_hygiene)]
#![plugin(rocket_codegen)]
extern crate juniper; extern crate juniper;
extern crate juniper_rocket; extern crate juniper_rocket;
extern crate rocket; #[macro_use] extern crate rocket;
use rocket::response::content; use rocket::response::content;
use rocket::State; use rocket::State;

View file

@ -36,8 +36,7 @@ Check the LICENSE file for details.
*/ */
#![feature(plugin)] #![feature(decl_macro, proc_macro_hygiene)]
#![plugin(rocket_codegen)]
extern crate juniper; extern crate juniper;
extern crate rocket; extern crate rocket;
@ -48,9 +47,9 @@ extern crate serde_derive;
use std::error::Error; use std::error::Error;
use std::io::{Cursor, Read}; use std::io::{Cursor, Read};
use rocket::data::{FromData, Outcome as FromDataOutcome}; use rocket::data::{FromDataSimple, Outcome as FromDataOutcome};
use rocket::http::{ContentType, Status}; use rocket::http::{ContentType, RawStr, Status};
use rocket::request::{FormItems, FromForm}; use rocket::request::{FormItems, FromForm, FromFormValue};
use rocket::response::{content, Responder, Response}; use rocket::response::{content, Responder, Response};
use rocket::Data; use rocket::Data;
use rocket::Outcome::{Failure, Forward, Success}; use rocket::Outcome::{Failure, Forward, Success};
@ -181,14 +180,14 @@ impl GraphQLResponse {
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # #![feature(plugin)] /// # #![feature(decl_macro, proc_macro_hygiene)]
/// # #![plugin(rocket_codegen)]
/// # /// #
/// # extern crate juniper; /// # extern crate juniper;
/// # extern crate juniper_rocket; /// # extern crate juniper_rocket;
/// # extern crate rocket; /// # #[macro_use] extern crate rocket;
/// # /// #
/// # use rocket::http::Cookies; /// # use rocket::http::Cookies;
/// # use rocket::request::Form;
/// # use rocket::response::content; /// # use rocket::response::content;
/// # use rocket::State; /// # use rocket::State;
/// # /// #
@ -197,11 +196,11 @@ impl GraphQLResponse {
/// # /// #
/// # type Schema = RootNode<'static, Database, EmptyMutation<Database>>; /// # type Schema = RootNode<'static, Database, EmptyMutation<Database>>;
/// # /// #
/// #[get("/graphql?<request>")] /// #[get("/graphql?<request..>")]
/// fn get_graphql_handler( /// fn get_graphql_handler(
/// mut cookies: Cookies, /// mut cookies: Cookies,
/// context: State<Database>, /// context: State<Database>,
/// request: juniper_rocket::GraphQLRequest, /// request: Form<juniper_rocket::GraphQLRequest>,
/// schema: State<Schema>, /// schema: State<Schema>,
/// ) -> juniper_rocket::GraphQLResponse { /// ) -> juniper_rocket::GraphQLResponse {
/// if cookies.get_private("user_id").is_none() { /// if cookies.get_private("user_id").is_none() {
@ -240,7 +239,8 @@ where
let mut operation_name = None; let mut operation_name = None;
let mut variables = None; let mut variables = None;
for (key, value) in form_items { for form_item in form_items {
let (key, value) = form_item.key_value();
// Note: we explicitly decode in the match arms to save work rather // Note: we explicitly decode in the match arms to save work rather
// than decoding every form item blindly. // than decoding every form item blindly.
match key.as_str() { match key.as_str() {
@ -299,7 +299,19 @@ where
} }
} }
impl<S> FromData for GraphQLRequest<S> impl<'v, S> FromFormValue<'v> for GraphQLRequest<S>
where S: ScalarValue
{
type Error = String;
fn from_form_value(form_value: &'v RawStr) -> Result<Self, Self::Error> {
let mut form_items = FormItems::from(form_value);
Self::from_form(&mut form_items, true)
}
}
impl<S> FromDataSimple for GraphQLRequest<S>
where where
S: ScalarValue, S: ScalarValue,
{ {
@ -447,7 +459,8 @@ mod fromform_tests {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use rocket; use rocket::{self, get, post, routes};
use rocket::request::Form;
use rocket::http::ContentType; use rocket::http::ContentType;
use rocket::local::{Client, LocalRequest}; use rocket::local::{Client, LocalRequest};
use rocket::Rocket; use rocket::Rocket;
@ -460,10 +473,10 @@ mod tests {
type Schema = RootNode<'static, Database, EmptyMutation<Database>>; type Schema = RootNode<'static, Database, EmptyMutation<Database>>;
#[get("/?<request>")] #[get("/?<request..>")]
fn get_graphql_handler( fn get_graphql_handler(
context: State<Database>, context: State<Database>,
request: super::GraphQLRequest, request: Form<super::GraphQLRequest>,
schema: State<Schema>, schema: State<Schema>,
) -> super::GraphQLResponse { ) -> super::GraphQLResponse {
request.execute(&schema, &context) request.execute(&schema, &context)
@ -512,8 +525,8 @@ mod tests {
)).mount("/", routes![post_graphql_handler, get_graphql_handler]) )).mount("/", routes![post_graphql_handler, get_graphql_handler])
} }
fn make_test_response<'r>(request: &LocalRequest<'r>) -> http_tests::TestResponse { fn make_test_response(request: &LocalRequest) -> http_tests::TestResponse {
let mut response = request.cloned_dispatch(); let mut response = request.clone().dispatch();
let status_code = response.status().code as i32; let status_code = response.status().code as i32;
let content_type = response let content_type = response
.content_type() .content_type()
@ -525,9 +538,9 @@ mod tests {
.into_string(); .into_string();
http_tests::TestResponse { http_tests::TestResponse {
status_code: status_code, status_code,
body: body, body,
content_type: content_type, content_type,
} }
} }
} }