Created
May 27, 2018 20:11
-
-
Save moorage/005aa094f924c89ab0892a5163cd94e5 to your computer and use it in GitHub Desktop.
Easy function to call GitHub's GraphQL server in Rust.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Example usage: | |
// let github_details = github_graphql_query( | |
// &"some_oauth_access_token", | |
// &"query { viewer { email name login id location websiteUrl } }", | |
// )?; | |
// | |
// Cargo.toml: | |
// .. | |
// [dependencies] | |
// rocket = "0.3.11" | |
// curl = "0.4" | |
// .. | |
extern crate curl; | |
use curl::easy::{Easy, List}; | |
const CONTENT_TYPE_JSON: &str = "application/json"; | |
const GITHUB_GRAPHQL_API: &str = "https://api.github.com/graphql"; | |
const GITHUB_APP_NAME: &str = "Example-App"; | |
// handles any Error Result and converts to a 500 error in Rocket (for use within a Rocket Web Application). | |
// CHANGEME to return any other type of useful error | |
macro_rules! error_to_500 { | |
($x:expr) => { | |
match $x { | |
Err(err) => { | |
eprintln!("{}", err.to_string()); | |
return Err(rocket::http::Status::InternalServerError); | |
} | |
Ok(_) => (), | |
} | |
}; | |
} | |
fn github_graphql_query(access_token: &str, graphql_query: &str) -> Result<String, Status> { | |
let mut easy = Easy::new(); | |
match easy.url(GITHUB_GRAPHQL_API) { | |
Err(err) => { | |
eprintln!("{}", err.to_string()); | |
return Err(rocket::http::Status::InternalServerError); | |
} | |
Ok(_) => (), | |
}; | |
let mut headers = List::new(); | |
error_to_500!(headers.append(&format!("User-Agent: {}", GITHUB_APP_NAME))); | |
error_to_500!(headers.append(&format!("Authorization: bearer {}", access_token))); | |
error_to_500!(headers.append(&format!("Accept: {}", CONTENT_TYPE_JSON))); | |
error_to_500!(easy.http_headers(headers)); | |
error_to_500!(easy.post(true)); | |
let query_json_str = format!("{{ \"query\": \"{}\" }}", graphql_query); | |
let mut query_json = query_json_str.as_bytes(); | |
error_to_500!(easy.post_field_size(query_json.len() as u64)); | |
let mut data = Vec::new(); | |
{ | |
let mut transfer = easy.transfer(); | |
error_to_500!(transfer.read_function(|buf| Ok(query_json.read(buf).unwrap_or(0)))); | |
error_to_500!(transfer.write_function(|new_data| { | |
data.extend_from_slice(new_data); | |
Ok(new_data.len()) | |
})); | |
error_to_500!(transfer.perform()); | |
} | |
let http_status_response = easy.response_code(); | |
error_to_500!(http_status_response); | |
let response_code = http_status_response.unwrap(); | |
if response_code != 200 { | |
eprintln!( | |
"Github API returned {} : {}", | |
response_code, | |
String::from_utf8_lossy(data.as_slice()) | |
); | |
return Err(rocket::http::Status::InternalServerError); | |
} | |
Ok(String::from_utf8_lossy(data.as_slice()).to_string()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment