#api-client #api #fetch #client #http #https

patron

hyper.rs库的包装器,允许针对特定远程API的客户端。此库可以作为单独的库使用,也可以作为特定远程API包装器的构建块。

3个不稳定版本

使用旧Rust 2015

0.2.1 2017年5月1日
0.2.0 2017年4月28日
0.1.0 2017年4月28日

HTTP客户端中排名第376

每月下载量约为40次

MIT许可证

22KB
568行(不含注释)

patron

hyper.rs库的包装器,允许针对特定远程API的客户端。此库可以作为单独的库使用,也可以作为特定远程API包装器的构建块。

接口

导出

我们希望提供一个拥有std::sync::Arc封装的客户端,以便用户在必要时可以在线程之间使用客户端。

pub type Client = std::sync::Arc<patron::Client>;

创建一个HTTP星战API客户端。

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())
);

使用OAuth2令牌创建HTTPS GitHub API客户端。

use patron;

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

使用基于查询的令牌创建HTTPS GitHub API客户端。

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()
);

创建CouchDB的HTTP客户端。

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()
);

ArangoDB的示例使用

此功能尚未完全实现,存在许多错误!

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("<replace_me>").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<String>
}
  
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()
);

设计

响应对象:[Fetch API](https://mdn.org.cn/en-US/docs/Web/API/Fetch_API)

备注

  • 客户端是否应该传递到发送方法中?
  • 我只想有一个请求配置表示,而不是当前的2个。
  • 更功能性的设计?
  • 我喜欢fetch API返回一个响应对象,并且能够以不同格式检索Body。如何将此与基于Result的良好接口一起呈现?
    client.get('/foo')
      .send()
      .unwrap()
      .json()
    
    send()将返回一个Response对象,您可以调用.json()。该方法将返回一个Result<serde_json::Value, Error>

依赖关系

~12–22MB
~423K SLoC