Skip to content

Commit

Permalink
Merge pull request #65 from tomhoule/release-0.2.0
Browse files Browse the repository at this point in the history
Improve docs, examples, error struct and release 0.2
  • Loading branch information
tomhoule committed Jul 22, 2018
2 parents 8cf0694 + 87b0acd commit 98373aa
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 35 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## Unreleased

## [0.2.0] - 2018-07-22

### Added

- Copy documentation from the GraphQL schema to the generated types (including their fields) as normal Rust documentation. Documentation will show up in the generated docs as well as IDEs that support expanding derive macros (which does not include the RLS yet).
- Implement and test deserializing subscription responses. We also try to provide helpful error messages when a subscription query is not valid (i.e. when it has more than one top-level field).
- Support the [new top-level errors shape from the June 2018 spec](https://github.com/facebook/graphql/blob/master/spec/Section%207%20--%20Response.md), except for the `extensions` field (see issue #64).

### Fixed

Expand Down
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "graphql_client"
version = "0.1.0"
version = "0.2.0"
authors = ["Tom Houlé <tom@tomhoule.com>"]
description = "Typed GraphQL requests and responses"
repository = "https://github.com/tomhoule/graphql-client"
Expand All @@ -11,7 +11,7 @@ categories = ["network-programming", "web-programming", "wasm"]
[dependencies]
failure = "0.1"
quote = "0.3"
graphql_query_derive = {path = "./graphql_query_derive", version = "0.1.0"}
graphql_query_derive = {path = "./graphql_query_derive", version = "0.2.0"}
graphql-parser = "0.2.0"
serde = "1.0"
serde_derive = "1.0"
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# graphql_client

[![Build Status](https://travis-ci.org/tomhoule/graphql-client.svg?branch=master)](https://travis-ci.org/tomhoule/graphql-client)
[![docs](https://docs.rs/graphql_client/badge.svg)](https://docs.rs/graphql_client/0.1.0/graphql_client/)
[![docs](https://docs.rs/graphql_client/badge.svg)](https://docs.rs/graphql_client/0.2.0/graphql_client/)
[![crates.io](https://img.shields.io/crates/v/graphql_client.svg)](https://crates.io/crates/graphql_client)

A typed GraphQL client library for Rust.
Expand All @@ -11,6 +11,8 @@ A typed GraphQL client library for Rust.
- Precise types for query variables and responses
- Supports GraphQL fragments, objects, unions, inputs, enums, custom scalars and input objects
- Works in the browser (WebAssembly)
- Subscriptions support (serialization-deserialization only at the moment)
- Copies documentation from the GraphQL schema to the generated Rust code

## Getting started

Expand Down
4 changes: 2 additions & 2 deletions examples/call_from_js/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ lto = "thin"
crate-type = ["cdylib"]

[dependencies]
graphql_client = { path = "../..", version = "0.1.0" }
wasm-bindgen = "0.2.11"
graphql_client = { path = "../..", version = "0.2.0" }
wasm-bindgen = "0.2.12"
serde = "1.0.67"
serde_derive = "1.0.67"
serde_json = "1.0.22"
Expand Down
7 changes: 5 additions & 2 deletions examples/call_from_js/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#![feature(proc_macro, wasm_custom_section, wasm_import_module)]
#![feature(wasm_custom_section, wasm_import_module, use_extern_macros)]

#[macro_use]
extern crate graphql_client;
Expand All @@ -18,7 +18,10 @@ use wasm_bindgen::prelude::*;
use graphql_client::*;

#[derive(GraphQLQuery)]
#[graphql(schema_path = "schema.json", query_path = "src/puppy_smiles.graphql")]
#[graphql(
schema_path = "schema.json",
query_path = "src/puppy_smiles.graphql"
)]
struct PuppySmiles;

#[wasm_bindgen]
Expand Down
2 changes: 2 additions & 0 deletions examples/github/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,5 @@ prettytable-rs = "0.7.0"
structopt = "0.2.10"
dotenv = "0.13.0"
envy = "0.3.2"
log = "0.4.3"
env_logger = "0.5.10"
14 changes: 14 additions & 0 deletions examples/github/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ extern crate envy;
extern crate failure;
#[macro_use]
extern crate graphql_client;
#[macro_use]
extern crate log;
extern crate env_logger;
extern crate reqwest;
extern crate serde;
extern crate serde_json;
Expand Down Expand Up @@ -45,6 +48,7 @@ fn parse_repo_name(repo_name: &str) -> Result<(&str, &str), failure::Error> {

fn main() -> Result<(), failure::Error> {
dotenv::dotenv().ok();
env_logger::init();

let config: Env = envy::from_env()?;

Expand All @@ -70,6 +74,16 @@ fn main() -> Result<(), failure::Error> {
.send()?;

let response_body: GraphQLResponse<query1::ResponseData> = res.json()?;
info!("{:?}", response_body);

if let Some(errors) = response_body.errors {
println!("there are errors:");

for error in &errors {
println!("{:?}", error);
}
}

let response_data: query1::ResponseData = response_body.data.expect("missing response data");

let stars: Option<i64> = response_data
Expand Down
4 changes: 2 additions & 2 deletions graphql_client_cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "graphql_client_cli"
description = "The CLI for graphql-client (WIP)"
version = "0.1.0"
version = "0.2.0"
authors = ["Tom Houlé <tom@tomhoule.com>"]
license = "Apache-2.0 OR MIT"

Expand All @@ -12,7 +12,7 @@ path = "src/main.rs"
[dependencies]
failure = "0.1"
reqwest = "0.8"
graphql_client = { version = "0.1.0", path = ".." }
graphql_client = { version = "0.2.0", path = ".." }
structopt = "0.2"
serde = "1.0"
serde_derive = "1.0"
Expand Down
4 changes: 2 additions & 2 deletions graphql_query_derive/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "graphql_query_derive"
version = "0.1.0"
version = "0.2.0"
authors = ["Tom Houlé <tom@tomhoule.com>"]
description = "Utility crate for graphql_client"
license = "Apache-2.0 OR MIT"
Expand All @@ -13,7 +13,7 @@ proc-macro = true
failure = "0.1"
quote = "^0.6"
syn = "0.14"
proc-macro2 = { version = "0.4" }
proc-macro2 = { version = "0.4", features = [] }
serde = "1.0"
serde_derive = "1.0"
serde_json = "1.0"
Expand Down
1 change: 0 additions & 1 deletion graphql_query_derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ mod inputs;
mod interfaces;
mod introspection_response;
mod objects;
mod operations;
mod query;
mod scalars;
mod schema;
Expand Down
21 changes: 0 additions & 21 deletions graphql_query_derive/src/operations.rs

This file was deleted.

89 changes: 87 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
//! The top-level documentation resides on the [project README](https://github.com/tomhoule/graphql-client) at the moment.
//!
//! The main interface to this library is the custom derive that generates modules from a GraphQL query and schema.

extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate graphql_query_derive;

#[cfg(test)]
#[macro_use]
extern crate serde_json;

#[doc(hidden)]
pub use graphql_query_derive::*;

Expand All @@ -27,16 +33,95 @@ where
pub query: &'static str,
}

#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Location {
line: i32,
column: i32,
}

#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum PathFragment {
Key(String),
Index(i32),
}

/// An element in the top-level `errors` array of a response body.
///
/// This tries to be as close to the spec as possible.
///
/// Spec: [https://github.com/facebook/graphql/blob/master/spec/Section%207%20--%20Response.md]
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct GraphQLError {
pub path: String,
pub message: String,
pub locations: Option<Vec<Location>>,
pub path: Option<Vec<PathFragment>>,
}

/// The generic shape taken by the responses of GraphQL APIs.
///
/// This will generally be used with the `ResponseData` struct from a derived module.
///
/// Spec: [https://github.com/facebook/graphql/blob/master/spec/Section%207%20--%20Response.md]
#[derive(Debug, Serialize, Deserialize)]
pub struct GraphQLResponse<Data> {
pub data: Option<Data>,
pub errors: Option<Vec<GraphQLError>>,
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn graphql_error_works_with_just_message() {
let err = json!({
"message": "I accidentally your whole query"
});

let deserialized_error: GraphQLError = serde_json::from_value(err).unwrap();

assert_eq!(
deserialized_error,
GraphQLError {
message: "I accidentally your whole query".to_string(),
locations: None,
path: None,
}
)
}

#[test]
fn full_graphql_error_deserialization() {
let err = json!({
"message": "I accidentally your whole query",
"locations": [{ "line": 3, "column": 13}, {"line": 56, "column": 1}],
"path": ["home", "alone", 3, "rating"]
});

let deserialized_error: GraphQLError = serde_json::from_value(err).unwrap();

assert_eq!(
deserialized_error,
GraphQLError {
message: "I accidentally your whole query".to_string(),
locations: Some(vec![
Location {
line: 3,
column: 13,
},
Location {
line: 56,
column: 1,
},
]),
path: Some(vec![
PathFragment::Key("home".to_owned()),
PathFragment::Key("alone".to_owned()),
PathFragment::Index(3),
PathFragment::Key("rating".to_owned()),
]),
}
)
}
}

0 comments on commit 98373aa

Please sign in to comment.