mirror of
https://github.com/rust-lang-nursery/rust-cookbook
synced 2024-11-22 19:43:06 +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]|
|
||||
| [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] |
|
||||
| [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)
|
||||
|
||||
|
@ -141,6 +143,8 @@ Keep lines sorted.
|
|||
[ex-rand-range]: basics.html#ex-rand-range
|
||||
[ex-rand-dist]: basics.html#ex-rand-dist
|
||||
[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-toml-config]: encoding.html#ex-toml-config
|
||||
[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]|
|
||||
| [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] |
|
||||
| [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
|
||||
<a name="ex-url-parse"/>
|
||||
|
@ -330,6 +332,122 @@ fn run() -> Result<()> {
|
|||
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 -->
|
||||
|
||||
[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
|
||||
[`join`]: https://docs.rs/url/1.*/url/struct.Url.html#method.join
|
||||
[`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
|
||||
[`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
|
||||
[`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::path`]: https://docs.rs/tempdir/*/tempdir/struct.TempDir.html#method.path
|
||||
|
|
Loading…
Reference in a new issue