by abonander

abonander / anterofit

Strongly typed, asynchronous REST client framework for Rust.

124 Stars 11 Forks Last release: Not found Other 300 Commits 0 Releases

Available items

No Items, yet!

The developer of this repository has not created any items for sale yet. Need a bug fixed? Help with integration? A different license? Create a request here:

anterofit Build Status On

Anterofit is a collection of Rust macros coupled to a lightweight, self-contained HTTP framework that allows you to easily create strongly-typed Rust wrappers for calling REST APIs.

// See examples/ for more details
#[macro_use] extern crate anterofit;
#[macro_use] extern crate serde_derive;

use anterofit::{Adapter, Url};

#[derive(Debug, Deserialize)] struct Post { pub userid: Option, pub id: u64, pub title: String, pub body: String }

service! { trait PostService { /// Get a Post by id. fn get_post(&self, id: u64) -> Post { GET("/posts/{}", id) }

    /// Get all posts.
    fn get_posts(&amp;self) -&gt; Vec<post> {

    /// Create a new Post under the given user ID with the given title and body.
    fn new_post(&amp;self, userid: u64, title: &amp;str, body: &amp;str) -&gt; Post {
        // We use the `EAGER:` keyword so we can use borrowed values in the body.
        // This serializes the body value immediately instead of waiting to serialize
        // it on the executor.
            "userid" =&gt; userid,
            "title": title,
            "body": body


fn main() { // Navigate to this URL in your browser for details. Very useful test API. let url = Url::parse("").unwrap();

let adapter = Adapter::builder()
    // When your REST API uses JSON in both requests and responses



/// Create a new Post. // All service traits are implemented for Adapter by default; using generics like this promotes good namespacing. fn create_post<p: postservice>(post_service: &P) { let post = post_service.new_post(42, "Hello", "World!") // Execute the request in the background and wait for it to complete .exec().block() .unwrap();

println!("{:?}", post);


/// Fetch the top 3 posts in the database. // Service traits are object-safe by default fn fetch_posts(post_service: &PostService) { let posts = post_service.get_posts() // Shorthand for .exec().block(), but executes the request on the current thread. .exec_here() .unwrap();

for post in posts.into_iter().take(3) {
    println!("{:?}", post);


Inspired by Square's Retrofit, as referenced in the name, Anterofit is even more strongly typed as everything that is feasible to check at compile-time, is. Runtime errors are, with few exceptions, reserved for error conditions that can only be discovered at runtime.


Get started with our User Guide

Or an in-depth look with our Documentation


Serde and JSON serialization:

Enabled by default with the


: ```toml [dependencies] anterofit = "0.1"

is required in the dependencies but not in the crate root.

serde = "0.9" serde_derive = "0.9" ```

Crate Root: ```rust

[macro_use] extern crate anterofit;

[macrouse] extern crate serdederive;

#### [`rustc-serialize`](


```toml [dependencies] rustc-serialize = "0.3"

[dependencies.anterofit] version = "0.1" default-features = false features = ["rustc-serialize"]

Crate Root: ```rust

[macro_use] extern crate anterofit;

extern crate rustc_serialize; ```


Licensed under either of

  • Apache License, Version 2.0, (LICENSE-APACHE or
  • MIT license (LICENSE-MIT or

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.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.