Skip to content

General (optional) Client by using reqwest (as developed by @tomhoule) #338

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

Closed
wants to merge 7 commits into from
Closed
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
38 changes: 19 additions & 19 deletions examples/web/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
[package]
name = "web"
version = "0.1.0"
authors = ["Tom Houlé <tom@tomhoule.com>"]
edition = "2018"
name = "web"
version = "0.1.0"

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

[dev-dependencies]
graphql_client = { path = "../../graphql_client" }
graphql_client_web = { path = "../../graphql_client_web" }
wasm-bindgen = "^0.2"
serde = { version = "1.0.67", features = ["derive"] }
graphql_client = {path = "../../graphql_client"}
graphql_client_web = {path = "../../graphql_client_web"}
js-sys = "0.3.44"
lazy_static = "1.0.1"
js-sys = "0.3.6"
futures = "0.1.25"
wasm-bindgen-futures = "0.3.6"
serde = {version = "1.0.67", features = ["derive"]}
wasm-bindgen = "^0.2"
wasm-bindgen-futures = "0.4.17"

[dev-dependencies.web-sys]
version = "0.3.6"
features = [
"console",
"Document",
"Element",
"EventTarget",
"Node",
"HtmlBodyElement",
"HtmlDocument",
"HtmlElement",
"console",
"Document",
"Element",
"EventTarget",
"Node",
"HtmlBodyElement",
"HtmlDocument",
"HtmlElement",
'MouseEvent',
]
version = "0.3.6"

[[example]]
name = "web"
crate-type = ["cdylib"]
name = "web"
19 changes: 11 additions & 8 deletions examples/web/examples/web.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use futures::Future;
use graphql_client::GraphQLQuery;
use lazy_static::*;
use std::cell::RefCell;
use std::sync::Mutex;
use wasm_bindgen::prelude::*;
use wasm_bindgen::JsCast;
use wasm_bindgen_futures::future_to_promise;
use wasm_bindgen_futures::spawn_local;

#[derive(GraphQLQuery)]
#[graphql(
Expand All @@ -23,15 +22,15 @@ lazy_static! {
static ref LAST_ENTRY: Mutex<RefCell<Option<String>>> = Mutex::new(RefCell::new(None));
}

fn load_more() -> impl Future<Item = JsValue, Error = JsValue> {
let client = graphql_client::web::Client::new("https://www.graphqlhub.com/graphql");
async fn load_more() -> Result<JsValue, JsValue> {
let client = graphql_client::http::Client::new("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);
let response = client.call(PuppySmiles, variables).await;

response
.map(|response| {
Expand Down Expand Up @@ -59,9 +58,13 @@ fn add_load_more_button() {
.create_element("button")
.expect_throw("could not create button");
btn.set_inner_html("I WANT MORE PUPPIES");
let on_click = Closure::wrap(
Box::new(move || future_to_promise(load_more())) as Box<dyn FnMut() -> js_sys::Promise>
);

let on_click = Closure::wrap(Box::new(move |_event: web_sys::MouseEvent| {
spawn_local(async {
load_more().await.unwrap();
});
}) as Box<dyn FnMut(_)>);

btn.add_event_listener_with_callback(
"click",
&on_click
Expand Down
66 changes: 30 additions & 36 deletions graphql_client/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,68 +1,62 @@
[package]
name = "graphql_client"
version = "0.9.0"
authors = ["Tom Houlé <tom@tomhoule.com>"]
description = "Typed GraphQL requests and responses"
repository = "https://github.com/graphql-rust/graphql-client"
license = "Apache-2.0 OR MIT"
keywords = ["graphql", "api", "web", "webassembly", "wasm"]
categories = ["network-programming", "web-programming", "wasm"]
description = "Typed GraphQL requests and responses"
edition = "2018"
keywords = ["graphql", "api", "web", "webassembly", "wasm"]
license = "Apache-2.0 OR MIT"
name = "graphql_client"
repository = "https://github.com/graphql-rust/graphql-client"
version = "0.9.0"

[dependencies]
anyhow = {version = "1.0", optional = true}
doc-comment = "^0.3"
anyhow = { version = "1.0", optional = true }
thiserror = { version = "1.0", optional = true }
graphql_query_derive = { path = "../graphql_query_derive", version = "0.9.0" }
graphql_query_derive = {path = "../graphql_query_derive", version = "0.9.0"}
reqwest = {version = "0.10.7", optional = true}
serde = {version = "^1.0.78", features = ["derive"]}
serde_json = "1.0"
serde = { version = "^1.0.78", features = ["derive"] }
thiserror = {version = "1.0", optional = true}

[dependencies.futures]
version = "^0.1"
optional = true
version = "^0.1"

[dependencies.js-sys]
version = "^0.3"
optional = true
version = "^0.3"

[dependencies.log]
version = "^0.4"
optional = true
version = "^0.4"

[dependencies.web-sys]
version = "^0.3"
optional = true
features = [
"Headers",
"Request",
"RequestInit",
"Response",
"Window",
"Headers",
"Request",
"RequestInit",
"Response",
"Window",
]
optional = true
version = "^0.3"

[dependencies.wasm-bindgen]
version = "^0.2"
optional = true
version = "^0.2"

[dependencies.wasm-bindgen-futures]
version = "^0.3"
optional = true

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
reqwest = "^0.9"
version = "^0.4"

[dev-dependencies]
# Note: If we bumpup wasm-bindge-test version, we should change CI setting.
wasm-bindgen-test = "^0.2"
wasm-bindgen-test = "^0.3"

[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
tokio = {version = "^0.2", features = ["rt-threaded", "macros"]}

[features]
web = [
"anyhow",
"thiserror",
"futures",
"js-sys",
"log",
"wasm-bindgen",
"wasm-bindgen-futures",
"web-sys",
]
default = ["http"]
http = ["reqwest"]
web = ["http"]
92 changes: 92 additions & 0 deletions graphql_client/src/http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
//! Some global

use crate::*;
use std::collections::HashMap;

/// The main interface to the library.
///
/// The workflow is the following:
///
/// - create a client
/// - (optionally) configure it
/// - use it to perform queries with the [call] method
pub struct Client {
endpoint: String,
headers: HashMap<String, String>,
reqwest_client: reqwest::Client,
}

impl Client {
/// Initialize a client. The `endpoint` parameter is the URI of the GraphQL API.
pub fn new<Endpoint>(endpoint: Endpoint) -> Client
where
Endpoint: Into<String>,
{
Client {
endpoint: endpoint.into(),
headers: HashMap::new(),
reqwest_client: reqwest::Client::new(),
}
}

/// Add a header to those sent with the requests. Can be used for things like authorization.
pub fn add_header(&mut self, name: &str, value: &str) {
self.headers.insert(name.into(), value.into());
}

/// Perform a query.
///
// Lint disabled: We can pass by value because it's always an empty struct.
#[allow(clippy::needless_pass_by_value)]
pub async fn call<Q: GraphQLQuery + 'static>(
&self,
_query: Q,
variables: Q::Variables,
) -> Result<crate::Response<Q::ResponseData>, ClientError> {
// TODO: remove tests and test harness
// TODO: custom headers
let reqwest_response = self
.reqwest_client
.post(&self.endpoint)
.header("Content-Type", "application/json")
.body(serde_json::to_string(&Q::build_query(variables)).unwrap())
.send()
.await?;

let text_response = reqwest_response.text().await?;

Ok(serde_json::from_str(&text_response)?)
}
}

/// TODO
#[derive(Debug)]
pub enum ClientError {
/// TODO
ReqwestError(reqwest::Error),
/// TODO
SerdeError(serde_json::Error),
}

impl From<reqwest::Error> for ClientError {
fn from(e: reqwest::Error) -> Self {
ClientError::ReqwestError(e)
}
}

impl From<serde_json::Error> for ClientError {
fn from(e: serde_json::Error) -> Self {
ClientError::SerdeError(e)
}
}

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

#[test]
fn client_new() {
Client::new("https://example.com/graphql");
Client::new("/graphql");
}
}
6 changes: 3 additions & 3 deletions graphql_client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,13 @@ pub use graphql_query_derive::*;

use serde::*;

#[cfg(feature = "web")]
pub mod web;
#[cfg(feature = "http")]
pub mod http;

use std::collections::HashMap;
use std::fmt::{self, Display};

doc_comment::doctest!("../../README.md");
//doc_comment::doctest!("../../README.md");

/// A convenience trait that can be used to build a GraphQL request body.
///
Expand Down
Loading