Skip to content

Instantly share code, notes, and snippets.

@AlexNisnevich
Created October 7, 2014 02:07
Show Gist options
  • Save AlexNisnevich/418be2ba34e130977f5c to your computer and use it in GitHub Desktop.
Save AlexNisnevich/418be2ba34e130977f5c to your computer and use it in GitHub Desktop.
JSON requests with rust-http
extern crate serialize;
extern crate http;
extern crate url;
use std::string::String;
use serialize::json;
use serialize::json::Json;
use serialize::json::ToJson;
use http::client::RequestWriter;
use http::headers::content_type::MediaType;
use http::headers::request;
use http::method;
use http::status;
use url::Url;
struct Request {
method: method::Method,
path: String,
headers: request::HeaderCollection,
body: Json
}
// Makes a JSON request with headers and body and expects a JSON response
// Returns one of:
// Ok(Some(response)) : successfully received JSON response
// Ok(None) : response is not valid JSON
// Err(error) : did not receive a 200 OK response
fn json_request(request_params: Request) -> Result<Option<Json>, String> {
let application_json = MediaType::new("application".to_string(), "json".to_string(), vec![]);
let url = Url::parse(request_params.path.as_slice()).ok().expect("path is not a valid URL");
let body_str = request_params.body.to_string();
let data: &[u8] = body_str.as_bytes();
let mut request: RequestWriter = RequestWriter::new(request_params.method, url).unwrap();
request.headers.content_length = Some(data.len());
request.headers.content_type = Some(application_json);
request.headers.accept = Some("*/*".to_string());
request.headers.user_agent = Some("Rust".to_string()); // (some APIs require a User-Agent)
for header in request_params.headers.iter() {
request.headers.insert(header);
}
request.write(data);
let mut response = request.read_response().ok().expect("Failed to send request");
let response_text: String = response.read_to_string().ok().expect("Failed to read response");
// println!("{}: {}", response.status, response_text);
match response.status {
status::Ok => Ok(json::from_str(response_text.as_slice()).ok()),
_ => Err(response_text)
}
}
fn main() {
// see http://doc.rust-lang.org/serialize/json/ to learn how to serialize datatypes into Json
// or pass your body as a raw Json string this way:
let empty_body = from_str::<Json>("{}").unwrap();
// see http://www.rust-ci.org/chris-morgan/rust-http/doc/http/headers/request/struct.HeaderCollection.html
// to learn how to add custom headers to a HeaderCollection
let empty_headers = request::HeaderCollection::new();
let request = Request {
method: method::Get, // available methods: http://www.rust-ci.org/chris-morgan/rust-http/doc/http/method/enum.Method.html
path: "https://api.github.com/users/AlexNisnevich".to_string(),
headers: empty_headers,
body: empty_body
};
match json_request(request) {
Ok(Some(response)) => println!("{}", response.to_pretty_str()),
Ok(None) => println!("JSON parsing error"),
Err(error) => println!("Request failed: {}", error)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment