Skip to content

Prepare for release #371

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jun 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 5 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ jobs:
override: true
- name: Execute cargo test
run: cargo test --all --tests --examples
wasm_test:
name: Cargo test for wasm
wasm_build:
name: Cargo build for wasm
runs-on: ubuntu-18.04
steps:
- name: Checkout sources
Expand All @@ -41,14 +41,10 @@ jobs:
profile: minimal
toolchain: stable
override: true
- name: Setup wasm-bindgen
target: wasm32-unknown-unknown
- name: Execute cargo build
run: |
rustup target add wasm32-unknown-unknown &&
sudo apt update && sudo apt install -y firefox-geckodriver &&
cargo install wasm-bindgen-cli
- name: Execute cargo test
run: |
xvfb-run cargo test --manifest-path=./graphql_client/Cargo.toml --features="web" --target wasm32-unknown-unknown
cargo build --manifest-path=./graphql_client/Cargo.toml --features="reqwest" --target wasm32-unknown-unknown
lint:
name: Rustfmt and Clippy
runs-on: ubuntu-latest
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ Cargo.lock
.idea
scripts/*
!scripts/*.sh
/.vscode
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## Unreleased

- [to be documnented] — A CLI and derive option to specify a module to import
custom scalar from. Thanks @miterst! ([PR](https://github.com/graphql-rust/graphql-client/pull/354))
- The `web` feature is dropped. You can now use a `reqwest::Client` instead of the custom HTTP client.
- Allow specifying externally defined enums (thanks @jakmeier)
- Make the derive feature optional (but enabled by default)
- `--no-ssl` param in CLI (thanks @danielharbor!)
- The shape of some generated response types changed to be flatter and more ergonomic.
- Many dependencies were dropped
— A CLI and derive option to specify a module to import custom scalar from.
Thanks @miterst! ([PR](https://github.com/graphql-rust/graphql-client/pull/354))

## 0.9.0 - 2020-03-13

Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[workspace]
resolver = "2"
members = [
"graphql_client",
"graphql_client_cli",
"graphql_client_codegen",
"graphql_client_web",
"graphql-introspection-query",
"graphql_query_derive",

Expand Down
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
[![Github actions Status](https://github.com/graphql-rust/graphql-client/workflows/CI/badge.svg?branch=master&event=push)](https://github.com/graphql-rust/graphql-client/actions)
[![docs](https://docs.rs/graphql_client/badge.svg)](https://docs.rs/graphql_client/latest/graphql_client/)
[![crates.io](https://img.shields.io/crates/v/graphql_client.svg)](https://crates.io/crates/graphql_client)
[![Join the chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/juniper-graphql/graphql-client)

A typed GraphQL client library for Rust.

Expand All @@ -19,7 +18,7 @@ A typed GraphQL client library for Rust.
- Supports multiple operations per query document.
- Supports setting GraphQL fields as deprecated and having the Rust compiler check
their use.
- [web client](./graphql_client_web) for boilerplate-free API calls from browsers.
- Optional reqwest-based client for boilerplate-free API calls from browsers.

## Getting started

Expand Down Expand Up @@ -84,6 +83,15 @@ A typed GraphQL client library for Rust.

[A complete example using the GitHub GraphQL API is available](https://github.com/graphql-rust/graphql-client/tree/master/examples/github), as well as sample [rustdoc output](https://www.tomhoule.com/docs/example_module/).

## Alternative workflow using the CLI

You can introspect GraphQL APIs and generate module from a command line interface to the library:

```bash
$ cargo install graphql_client_cli
$ graphql-client --help
```

## Deriving specific traits on the response

The generated response types always derive `serde::Deserialize` but you may want to print them (`Debug`), compare them (`PartialEq`) or derive any other trait on it. You can achieve this with the `response_derives` option of the `graphql` attribute. Example:
Expand Down
6 changes: 2 additions & 4 deletions examples/github/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ edition = "2018"

[dev-dependencies]
anyhow = "1.0"
graphql_client = { path = "../../graphql_client" }
graphql_client = { path = "../../graphql_client", features = ["reqwest-blocking"] }
serde = "^1.0"
reqwest = { version = "^0.10", features = ["json", "blocking"] }
reqwest = { version = "^0.11", features = ["json", "blocking"] }
prettytable-rs = "^0.7"
structopt = "^0.3"
dotenv = "^0.13"
envy = "^0.3"
log = "^0.4"
env_logger = "^0.5"
46 changes: 22 additions & 24 deletions examples/github/examples/github.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use ::reqwest::blocking::Client;
use anyhow::*;
use graphql_client::*;
use graphql_client::{reqwest::post_graphql_blocking as post_graphql, GraphQLQuery};
use log::*;
use prettytable::*;
use serde::*;
use structopt::StructOpt;

#[allow(clippy::upper_case_acronyms)]
type URI = String;

#[derive(GraphQLQuery)]
Expand All @@ -22,11 +23,6 @@ struct Command {
repo: String,
}

#[derive(Deserialize, Debug)]
struct Env {
github_api_token: String,
}

fn parse_repo_name(repo_name: &str) -> Result<(&str, &str), anyhow::Error> {
let mut parts = repo_name.split('/');
match (parts.next(), parts.next()) {
Expand All @@ -36,34 +32,36 @@ fn parse_repo_name(repo_name: &str) -> Result<(&str, &str), anyhow::Error> {
}

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

let config: Env = envy::from_env().context("while reading from environment")?;
let github_api_token =
std::env::var("GITHUB_API_TOKEN").expect("Missing GITHUB_API_TOKEN env var");

let args = Command::from_args();

let repo = args.repo;
let (owner, name) = parse_repo_name(&repo).unwrap_or(("tomhoule", "graphql-client"));

let q = RepoView::build_query(repo_view::Variables {
let variables = repo_view::Variables {
owner: owner.to_string(),
name: name.to_string(),
});
};

let client = reqwest::blocking::Client::builder()
let client = Client::builder()
.user_agent("graphql-rust/0.9.0")
.default_headers(
std::iter::once((
reqwest::header::AUTHORIZATION,
reqwest::header::HeaderValue::from_str(&format!("Bearer {}", github_api_token))
.unwrap(),
))
.collect(),
)
.build()?;

let res = client
.post("https://api.github.com/graphql")
.bearer_auth(config.github_api_token)
.json(&q)
.send()?;

res.error_for_status_ref()?;
let response_body =
post_graphql::<RepoView, _>(&client, "https://api.github.com/graphql", variables).unwrap();

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

let response_data: repo_view::ResponseData = response_body.data.expect("missing response data");
Expand All @@ -79,16 +77,16 @@ fn main() -> Result<(), anyhow::Error> {
table.set_format(*prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE);
table.set_titles(row!(b => "issue", "comments"));

for issue in &response_data
for issue in response_data
.repository
.expect("missing repository")
.issues
.nodes
.expect("issue nodes is null")
.iter()
.flatten()
{
if let Some(issue) = issue {
table.add_row(row!(issue.title, issue.comments.total_count));
}
table.add_row(row!(issue.title, issue.comments.total_count));
}

table.printstd();
Expand Down
8 changes: 3 additions & 5 deletions examples/hasura/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@ edition = "2018"

[dev-dependencies]
anyhow = "1.0"
graphql_client = { path = "../../graphql_client" }
serde = "1.0"
serde_derive = "1.0"
graphql_client = { path = "../../graphql_client", features = ["reqwest-blocking"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
reqwest = { version = "^0.10", features = ["json", "blocking"] }
reqwest = { version = "^0.11", features = ["json", "blocking"] }
prettytable-rs = "0.7.0"
dotenv = "0.13.0"
log = "0.4.3"
env_logger = "0.5.10"
18 changes: 7 additions & 11 deletions examples/hasura/examples/hasura.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use graphql_client::*;
use ::reqwest::blocking::Client;
use graphql_client::{reqwest::post_graphql_blocking as post_graphql, GraphQLQuery};
use log::*;
use prettytable::*;

Expand All @@ -16,27 +17,22 @@ struct UpsertIssue;

fn main() -> Result<(), anyhow::Error> {
use upsert_issue::{IssuesUpdateColumn::*, *};
dotenv::dotenv().ok();
env_logger::init();

let q = UpsertIssue::build_query(Variables {
let v = Variables {
issues: vec![IssuesInsertInput {
id: Some("001000000000000".to_string()),
name: Some("Name".to_string()),
status: Some("Draft".to_string()),
salesforce_updated_at: Some("2019-06-11T08:14:28Z".to_string()),
}],
update_columns: vec![Name, Status, SalesforceUpdatedAt],
});
};

let client = reqwest::blocking::Client::new();
let client = Client::new();

let res = client
.post("https://localhost:8080/v1/graphql")
.json(&q)
.send()?;

let response_body: Response<ResponseData> = res.json()?;
let response_body =
post_graphql::<UpsertIssue, _>(&client, "https://localhost:8080/v1/graphql", v)?;
info!("{:?}", response_body);

if let Some(errors) = response_body.errors {
Expand Down
19 changes: 7 additions & 12 deletions examples/web/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,19 @@ version = "0.1.0"
authors = ["Tom Houlé <tom@tomhoule.com>"]
edition = "2018"

# https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#profile-overrides
#[profile.release]
#lto = "thin"
[lib]
crate-type = ["cdylib", "rlib"]

[dev-dependencies]
graphql_client = { path = "../../graphql_client" }
graphql_client_web = { path = "../../graphql_client_web" }
[dependencies]
graphql_client = { path = "../../graphql_client", features = ["reqwest"] }
wasm-bindgen = "^0.2"
serde = { version = "1.0.67", features = ["derive"] }
lazy_static = "1.0.1"
js-sys = "0.3.6"
futures-util = "0.3.8"
wasm-bindgen-futures = "0.4.18"
reqwest = "0.11.3"

[dev-dependencies.web-sys]
[dependencies.web-sys]
version = "0.3.6"
features = [
"console",
Expand All @@ -29,8 +27,5 @@ features = [
"HtmlBodyElement",
"HtmlDocument",
"HtmlElement",
"Window",
]

[[example]]
name = "web"
crate-type = ["cdylib"]
42 changes: 21 additions & 21 deletions examples/web/examples/web.rs → examples/web/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use graphql_client::GraphQLQuery;
use graphql_client::{reqwest::post_graphql, GraphQLQuery};
use lazy_static::*;
use std::cell::RefCell;
use std::sync::Mutex;
Expand All @@ -9,7 +9,7 @@ use wasm_bindgen_futures::future_to_promise;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "schema.json",
query_path = "examples/puppy_smiles.graphql",
query_path = "src/puppy_smiles.graphql",
response_derives = "Debug"
)]
struct PuppySmiles;
Expand All @@ -23,20 +23,22 @@ lazy_static! {
}

async fn load_more() -> Result<JsValue, JsValue> {
let client = graphql_client::web::Client::new("https://www.graphqlhub.com/graphql");
let url = "https://www.graphqlhub.com/graphql";
let variables = puppy_smiles::Variables {
after: LAST_ENTRY
.lock()
.ok()
.and_then(|opt| opt.borrow().to_owned()),
};
let response = client.call(PuppySmiles, variables).await.map_err(|err| {
log(&format!(
"Could not fetch puppies. graphql_client_web error: {:?}",
err
));
JsValue::NULL
})?;

let client = reqwest::Client::new();

let response = post_graphql::<PuppySmiles, _>(&client, url, variables)
.await
.map_err(|err| {
log(&format!("Could not fetch puppies. error: {:?}", err));
JsValue::NULL
})?;
render_response(response);
Ok(JsValue::NULL)
}
Expand Down Expand Up @@ -72,14 +74,14 @@ fn add_load_more_button() {
on_click.forget();
}

fn render_response(response: graphql_client_web::Response<puppy_smiles::ResponseData>) {
fn render_response(response: graphql_client::Response<puppy_smiles::ResponseData>) {
use std::fmt::Write;

log(&format!("response body\n\n{:?}", response));

let parent = document().body().expect_throw("no body");

let json: graphql_client_web::Response<puppy_smiles::ResponseData> = response;
let json: graphql_client::Response<puppy_smiles::ResponseData> = response;
let response = document()
.create_element("div")
.expect_throw("could not create div");
Expand All @@ -98,22 +100,20 @@ fn render_response(response: graphql_client_web::Response<puppy_smiles::Response
.map(|puppy| puppy.fullname_id.clone());
LAST_ENTRY.lock().unwrap_throw().replace(new_cursor);

for puppy in &listings {
if let Some(puppy) = puppy {
write!(
inner_html,
r#"
for puppy in listings.iter().flatten() {
write!(
inner_html,
r#"
<div class="card" style="width: 26rem;">
<img class="img-thumbnail card-img-top" alt="{}" src="{}" />
<div class="card-body">
<h5 class="card-title">{}</h5>
</div>
</div>
"#,
puppy.title, puppy.url, puppy.title
)
.expect_throw("write to string");
}
puppy.title, puppy.url, puppy.title
)
.expect_throw("write to string");
}
response.set_inner_html(&format!(
"<h2>response:</h2><div class=\"container\"><div class=\"row\">{}</div></div>",
Expand Down
Loading