Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/scull7/patron

A wrapper around the hyper.rs library to allow for targeted clients to specific remote APIs.
https://github.com/scull7/patron

Last synced: about 1 month ago
JSON representation

A wrapper around the hyper.rs library to allow for targeted clients to specific remote APIs.

Awesome Lists containing this project

README

        

# patron
A wrapper around the hyper.rs library to allow for targeted clients to
specific remote APIs. This library should be useful on it's own or as a
building block for specific remote API wrappers.

## The Interface

### Exports
We want to give out an owned `std::sync::Arc` wrapped client so that the user can
utilize the client between threads if ncessary.

```rust
pub type Client = std::sync::Arc;

```

### Create an HTTP Star Wars API client.
```rust
struct Person {
name: String,
birth_year: String,
eye_color: String,
height: String,
mass: String,
}

let client = try!(patron::from_str("http://swapi.co/api")
.build()
);

let han_solo: Person = try!client.get("/people/14")
.send()
.and_then(|res| res.deserialize())
);
```

### Creating an HTTPs GitHub Api client with an OAuth2 token.
```rust
use patron;

let client: patron::Client = try!(
patron::from_str("https://api.github.com")
.set_oauth_token("0b79bab50daca910b000d4f1a2b675d604257e42")
.build()
);
```

### Creating an HTTPs GitHub Api client using query based tokens.
```rust
use patron;

let client: patron::Client = try!(
patron::from_str("https://api.github.com")
.add_query_param("client_id", "ABCDEFGHIKLMNOP")
.add_query_param("client_secret", "QRSTUVWXYZABCDE")
.build()
);
```

### Creating an HTTP client for CouchDB.
```rust
use patron;

let url: patron::Url = try!(
patron::Url::new()
.set_scheme(patron::Scheme::Http)
.set_host('localhost')
.set_port(5984)
.build()
);

let client: patron::Client = try!(
patron::from_url(url)
.add_path("somedatabase")
.basic_auth("anna", "secret")
.build()
);
```

### Example usage for ArangoDB
***THIS IS NOT FULLY IMPLEMENTED, LIES ABOUND!***
```rust
use serde_json;
use patron;

#[derive(Debug, Deserialize)]
struct AuthRes {
jwt: String,
must_change_password: bool,
}

// Generally this would be built from some configuration object.
let mut url = patron::url::Url::new()
url.set_scheme(patron::Scheme::Http)
url.set_host("localhost")
url.set_port(8529)

let auth: AuthRes = try!(
patron::Request::new(url)
.post("/_open/auth")
.add_body_param("username", "root")
.add_body_param("password", "password")
.send()
);

let mydb_client: patron::Client = try!(
patron::from_url(url)
.set_oauth_token(auth.jwt)
.add_path("/_db/mydb/")
.build()
);

#[derive(Debug, Deserialize)]
struct Version {
version: String,
server: String,
}

let version: Version = try!(client.get("/_api/version").send());

#[derive(Debug, Deserialize, Serialize)]
struct NewDoc {
#[serde(rename = "_key")]
key: String,
#[serde(rename = "_id")]
id: String,
#[serde(rename = "_rev")]
revision: String,
}

let newdoc: NewDoc = try!(
client.post("/_api/demo")
.add_body_param("message", serde_json::to_value("").unwrap())
.add_query_param("waitForSync", "true")
.send()
);

#[derive(Debug, Deserialize, Serialize)]
struct Document {
#[serde(rename = "_key")]
key: String,
#[serde(rename = "_id")]
id: String,
#[serde(rename = "_rev")]
revision: String,
message: Option
}

let mut hello: Document = try!(
client.get("/_api/document/demo/")
.add_path(newdoc.id)
.send()
);

hello.message = Some("Hello, World!");

#[derive(Debug, Deserialize, Serialize)]
struct UpdateRes {
#[serde(rename = "_key")]
key: String,
#[serde(rename = "_id")]
id: String,
#[serde(rename = "_rev")]
revision: String,
#[serde(rename = "_oldRev")]
previous_revision: String,
}

let res: UpdateRes = try!(
client.put("/api/document/demo")
.add_path(hello.id)
.set_body(hello)
.send()
);
```

### Design
Response Objects: [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)

### Notes
* Should the client be passed into the send method?
* I would like to only have one representation of a request configuration instead of the current 2.
* A more functional style design?
* I like how the fetch API returns a response object with the ability to retrieve the `Body` in
different formats. How can this be presented along with a nice `Result` based interface?
```rust
client.get('/foo')
.send()
.unwrap()
.json()
```
`send()` will return a `Response` object which you can call `.json()`. The `.json()` method will return
a `Result`