#web #client #http #impl


Automatic & type-safe API clients - provide the interface and i will happily do the rest :)

5 releases

0.0.6 Jun 13, 2021
0.0.5 Jun 12, 2021
0.0.4 Jun 12, 2021
0.0.2 Jun 11, 2021
0.0.1 Jun 11, 2021

#249 in Web programming


130 lines

crates.io docs.rs Maintenance


an auto-impl http client that will leave you happi :)

This includes a CI/CD pipeline, README templating, and cargo-make scripts.


Using an example of https://reqres.in/, a happi implementation of this would look something like:

pub fn main() -> Result<(), dyn std::error::Error> {
  let reqres = ReqResApi(reqwest::blocking::Client::new());

  let user_page = reqres.get_all_users(None)?;

  println!("{:#?}", user_page);

// This is the *real* client that hits the API
#[happi(base_url = "https://reqres.in/api", blocking)]
pub struct ReqResApi(#[client] hyper::Client);

// This is a trait for the `user` resource that `happi`
// will implement for `ReqResApi`.
// When you want to use this resource, your function can
// accept an `impl reqres::UserResource`, accepting the real
// deal or a mock when you write tests.
  responds(200, json),
pub trait UserResource {
  pub fn get_all_users(&self, #[query] page: Option<u32>) -> Result<UserPage, happi::Error>;

    responds(404, unit),
    when(status == 404, invoke = |_resp| Ok(None)),
  pub fn get_user(&self, id: u32) -> Result<Option<User>, happi::Error>;

#[derive(Debug, Serialize, Deserialize)]
pub struct User {
  id: u32,
  first_name: String,
  last_name: String,
  avatar: String,

#[derive(Debug, Serialize, Deserialize)]
pub struct UserPage {
  page: u32,
  per_page: u32,
  total: u32,
  total_pages: u32,
  data: Vec<User>


Licensed under either of

at your option.


Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.


~142K SLoC