mirror of
https://github.com/rust-lang-nursery/rust-cookbook
synced 2024-11-26 21:40:17 +00:00
Merge pull request #80 from budziq/rest_github
Implemented two examples for "Query the GitHub API"
This commit is contained in:
commit
b56eb82073
2 changed files with 131 additions and 0 deletions
|
@ -52,6 +52,8 @@ community. It needs and welcomes help. For details see
|
||||||
| [Serialize a `Url`][ex-url-serialize] | [![url-badge]][url] [![serde-badge]][serde] | [![cat-net-badge]][cat-net] [![cat-encoding-badge]][cat-encoding]|
|
| [Serialize a `Url`][ex-url-serialize] | [![url-badge]][url] [![serde-badge]][serde] | [![cat-net-badge]][cat-net] [![cat-encoding-badge]][cat-encoding]|
|
||||||
| [Make a HTTP GET request after parsing a URL][ex-url-basic] | [![reqwest-badge]][reqwest] | [![cat-net-badge]][cat-net] |
|
| [Make a HTTP GET request after parsing a URL][ex-url-basic] | [![reqwest-badge]][reqwest] | [![cat-net-badge]][cat-net] |
|
||||||
| [Download a file to a temporary directory][ex-url-download] | [![reqwest-badge]][reqwest] [![tempdir-badge]][tempdir] | [![cat-net-badge]][cat-net] [![cat-filesystem-badge]][cat-filesystem] |
|
| [Download a file to a temporary directory][ex-url-download] | [![reqwest-badge]][reqwest] [![tempdir-badge]][tempdir] | [![cat-net-badge]][cat-net] [![cat-filesystem-badge]][cat-filesystem] |
|
||||||
|
| [Query the GitHub API][ex-rest-get] | [![reqwest-badge]][reqwest] [![serde-badge]][serde] | [![cat-net-badge]][cat-net] [![cat-encoding-badge]][cat-encoding] |
|
||||||
|
| [Create and delete Gist with GitHub API][ex-rest-post] | [![reqwest-badge]][reqwest] [![serde-badge]][serde] | [![cat-net-badge]][cat-net] [![cat-encoding-badge]][cat-encoding] |
|
||||||
|
|
||||||
## [Application development](app.html)
|
## [Application development](app.html)
|
||||||
|
|
||||||
|
@ -141,6 +143,8 @@ Keep lines sorted.
|
||||||
[ex-rand-range]: basics.html#ex-rand-range
|
[ex-rand-range]: basics.html#ex-rand-range
|
||||||
[ex-rand-dist]: basics.html#ex-rand-dist
|
[ex-rand-dist]: basics.html#ex-rand-dist
|
||||||
[ex-rayon-iter-mut]: concurrency.html#ex-rayon-iter-mut
|
[ex-rayon-iter-mut]: concurrency.html#ex-rayon-iter-mut
|
||||||
|
[ex-rest-get]: net.html#ex-rest-get
|
||||||
|
[ex-rest-post]: net.html#ex-rest-post
|
||||||
[ex-std-read-lines]: basics.html#ex-std-read-lines
|
[ex-std-read-lines]: basics.html#ex-std-read-lines
|
||||||
[ex-toml-config]: encoding.html#ex-toml-config
|
[ex-toml-config]: encoding.html#ex-toml-config
|
||||||
[ex-url-parse]: net.html#ex-url-parse
|
[ex-url-parse]: net.html#ex-url-parse
|
||||||
|
|
127
src/net.md
127
src/net.md
|
@ -10,6 +10,8 @@
|
||||||
| [Serialize a `Url`][ex-url-serialize] | [![url-badge]][url] [![serde-badge]][serde] | [![cat-net-badge]][cat-net] [![cat-encoding-badge]][cat-encoding]|
|
| [Serialize a `Url`][ex-url-serialize] | [![url-badge]][url] [![serde-badge]][serde] | [![cat-net-badge]][cat-net] [![cat-encoding-badge]][cat-encoding]|
|
||||||
| [Make a HTTP GET request][ex-url-basic] | [![reqwest-badge]][reqwest] | [![cat-net-badge]][cat-net] |
|
| [Make a HTTP GET request][ex-url-basic] | [![reqwest-badge]][reqwest] | [![cat-net-badge]][cat-net] |
|
||||||
| [Download a file to a temporary directory][ex-url-download] | [![reqwest-badge]][reqwest] [![tempdir-badge]][tempdir] | [![cat-net-badge]][cat-net] [![cat-filesystem-badge]][cat-filesystem] |
|
| [Download a file to a temporary directory][ex-url-download] | [![reqwest-badge]][reqwest] [![tempdir-badge]][tempdir] | [![cat-net-badge]][cat-net] [![cat-filesystem-badge]][cat-filesystem] |
|
||||||
|
| [Query the GitHub API][ex-rest-get] | [![reqwest-badge]][reqwest] [![serde-badge]][serde] | [![cat-net-badge]][cat-net] [![cat-encoding-badge]][cat-encoding] |
|
||||||
|
| [Create and delete Gist with GitHub API][ex-rest-post] | [![reqwest-badge]][reqwest] [![serde-badge]][serde] | [![cat-net-badge]][cat-net] [![cat-encoding-badge]][cat-encoding] |
|
||||||
|
|
||||||
[ex-url-parse]: #ex-url-parse
|
[ex-url-parse]: #ex-url-parse
|
||||||
<a name="ex-url-parse"/>
|
<a name="ex-url-parse"/>
|
||||||
|
@ -330,6 +332,122 @@ fn run() -> Result<()> {
|
||||||
quick_main!(run);
|
quick_main!(run);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
[ex-rest-get]: #ex-rest-get
|
||||||
|
<a name="ex-rest-get"/>
|
||||||
|
## Query the GitHub API
|
||||||
|
|
||||||
|
[![reqwest-badge]][reqwest] [![serde-badge]][serde] [![cat-net-badge]][cat-net] [![cat-encoding-badge]][cat-encoding]
|
||||||
|
|
||||||
|
GitHub [stargazers API v3](https://developer.github.com/v3/activity/starring/#list-stargazers) is queried with [`reqwest::get`] to obtain list of all users who have marked a GitHub project with a star. [`reqwest::Response`] is deserialized with [`Response::json`] into `User` objects implementing [`serde::Deserialize`].
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
extern crate reqwest;
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct User {
|
||||||
|
login: String,
|
||||||
|
id: u32,
|
||||||
|
// remaining fields not deserialized for brevity
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run() -> reqwest::Result<()> {
|
||||||
|
let request_url = format!("https://api.github.com/repos/{owner}/{repo}/stargazers",
|
||||||
|
owner = "brson",
|
||||||
|
repo = "rust-cookbook");
|
||||||
|
println!("{}", request_url);
|
||||||
|
let mut response = reqwest::get(&request_url)?;
|
||||||
|
|
||||||
|
let users: Vec<User> = response.json()?;
|
||||||
|
println!("{:?}", users);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
run().unwrap();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
[ex-rest-post]: #ex-rest-post
|
||||||
|
<a name="ex-rest-post"/>
|
||||||
|
## Create and delete Gist with GitHub API
|
||||||
|
|
||||||
|
[![reqwest-badge]][reqwest] [![serde-badge]][serde] [![cat-net-badge]][cat-net] [![cat-encoding-badge]][cat-encoding]
|
||||||
|
|
||||||
|
HTTP POST request to [gists API v3](https://developer.github.com/v3/gists/) is made with [`reqwest::Client`] in order to create a gist.
|
||||||
|
A request body is created with [`serde_json::json!`] macro and
|
||||||
|
set set with [`RequestBuilder::json`].
|
||||||
|
Request is prepared with [`Client::post`], authenticated with [`RequestBuilder::basic_auth`] and synchronously executed with [`RequestBuilder::send`].
|
||||||
|
|
||||||
|
Gist is subsequently deleted with HTTP DELETE request prepared with [`Client::delete`] and executed as before.
|
||||||
|
|
||||||
|
```rust,no_run
|
||||||
|
#[macro_use]
|
||||||
|
extern crate error_chain;
|
||||||
|
extern crate reqwest;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_derive;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_json;
|
||||||
|
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
error_chain! {
|
||||||
|
foreign_links {
|
||||||
|
EnvVar(env::VarError);
|
||||||
|
HttpReqest(reqwest::Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug)]
|
||||||
|
struct Gist {
|
||||||
|
id: String,
|
||||||
|
html_url: String,
|
||||||
|
// remaining fields not deserialized for brevity
|
||||||
|
}
|
||||||
|
|
||||||
|
fn run() -> Result<()> {
|
||||||
|
let gh_user = env::var("GH_USER")?;
|
||||||
|
let gh_pass = env::var("GH_PASS")?;
|
||||||
|
|
||||||
|
// The type `gist_body` is `serde_json::Value`
|
||||||
|
let gist_body = json!({
|
||||||
|
"description": "the description for this gist",
|
||||||
|
"public": true,
|
||||||
|
"files": {
|
||||||
|
"main.rs": {
|
||||||
|
"content": r#"fn main() { println!("hello world!");}"#
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
|
||||||
|
// create the gist
|
||||||
|
let request_url = "https://api.github.com/gists";
|
||||||
|
let client = reqwest::Client::new()?;
|
||||||
|
let mut response = client
|
||||||
|
.post(request_url)
|
||||||
|
.basic_auth(gh_user.clone(), Some(gh_pass.clone()))
|
||||||
|
.json(&gist_body)
|
||||||
|
.send()?;
|
||||||
|
|
||||||
|
let gist: Gist = response.json()?;
|
||||||
|
println!("Created {:?}", gist);
|
||||||
|
|
||||||
|
// delete the gist
|
||||||
|
let request_url = format!("{}/{}",request_url, gist.id);
|
||||||
|
let client = reqwest::Client::new()?;
|
||||||
|
let response = client
|
||||||
|
.delete(&request_url)
|
||||||
|
.basic_auth(gh_user, Some(gh_pass))
|
||||||
|
.send()?;
|
||||||
|
|
||||||
|
println!("Gist {} deleted! Status code: {}",gist.id, response.status());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
quick_main!(run);
|
||||||
|
```
|
||||||
|
|
||||||
<!-- Categories -->
|
<!-- Categories -->
|
||||||
|
|
||||||
[cat-encoding-badge]: https://img.shields.io/badge/-encoding-red.svg
|
[cat-encoding-badge]: https://img.shields.io/badge/-encoding-red.svg
|
||||||
|
@ -360,9 +478,18 @@ quick_main!(run);
|
||||||
[`origin`]: https://docs.rs/url/1.*/url/struct.Url.html#method.origin
|
[`origin`]: https://docs.rs/url/1.*/url/struct.Url.html#method.origin
|
||||||
[`join`]: https://docs.rs/url/1.*/url/struct.Url.html#method.join
|
[`join`]: https://docs.rs/url/1.*/url/struct.Url.html#method.join
|
||||||
[`reqwest::get`]: https://docs.rs/reqwest/*/reqwest/fn.get.html
|
[`reqwest::get`]: https://docs.rs/reqwest/*/reqwest/fn.get.html
|
||||||
|
[`reqwest::Client`]: https://docs.rs/reqwest/*/reqwest/struct.Client.html
|
||||||
[`reqwest::Response`]: https://docs.rs/reqwest/*/reqwest/struct.Response.html
|
[`reqwest::Response`]: https://docs.rs/reqwest/*/reqwest/struct.Response.html
|
||||||
[`Response::url`]: https://docs.rs/reqwest/*/reqwest/struct.Response.html#method.url
|
[`Response::url`]: https://docs.rs/reqwest/*/reqwest/struct.Response.html#method.url
|
||||||
|
[`Response::json`]: https://docs.rs/reqwest/*/reqwest/struct.Response.html#method.json
|
||||||
|
[`RequestBuilder::basic_auth`]: https://docs.rs/reqwest/*/reqwest/struct.RequestBuilder.html#method.basic_auth
|
||||||
|
[`Client::delete`]: https://docs.rs/reqwest/*/reqwest/struct.Client.html#method.delete
|
||||||
|
[`Client::post`]: https://docs.rs/reqwest/*/reqwest/struct.Client.html#method.post
|
||||||
|
[`RequestBuilder::json`]: https://docs.rs/reqwest/*/reqwest/struct.RequestBuilder.html#method.json
|
||||||
|
[`RequestBuilder::send`]: https://docs.rs/reqwest/*/reqwest/struct.RequestBuilder.html#method.send
|
||||||
[`read_to_string`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_to_string
|
[`read_to_string`]: https://doc.rust-lang.org/std/io/trait.Read.html#method.read_to_string
|
||||||
[`String`]: https://doc.rust-lang.org/std/string/struct.String.html
|
[`String`]: https://doc.rust-lang.org/std/string/struct.String.html
|
||||||
|
[`serde::Deserialize`]: https://docs.rs/serde/*/serde/trait.Deserialize.html
|
||||||
|
[`serde_json::json!`]: https://docs.rs/serde_json/*/serde_json/macro.json.html
|
||||||
[`TempDir::new`]: https://docs.rs/tempdir/*/tempdir/struct.TempDir.html#method.new
|
[`TempDir::new`]: https://docs.rs/tempdir/*/tempdir/struct.TempDir.html#method.new
|
||||||
[`TempDir::path`]: https://docs.rs/tempdir/*/tempdir/struct.TempDir.html#method.path
|
[`TempDir::path`]: https://docs.rs/tempdir/*/tempdir/struct.TempDir.html#method.path
|
||||||
|
|
Loading…
Reference in a new issue