• Stars
    star
    134
  • Rank 270,967 (Top 6 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created about 8 years ago
  • Updated over 4 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Strongly typed, asynchronous REST client framework for Rust.

anterofit Build Status On Crates.io

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/post_service.rs 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<u64>,
    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(&self) -> Vec<Post> {
            GET("/posts")
        }

        /// Create a new Post under the given user ID with the given title and body.
        fn new_post(&self, userid: u64, title: &str, body: &str) -> Post {
            POST("/posts/");
            // 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.
            body_map!(EAGER:
                "userid" => userid,
                "title": title,
                "body": body
            )
        }
    }
}

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

    let adapter = Adapter::builder()
        .base_url(url)
        // When your REST API uses JSON in both requests and responses
        .serialize_json()
        .build();

    create_post(&adapter);
    fetch_posts(&adapter);
}

/// 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.

Usage

Get started with our User Guide

Or an in-depth look with our Documentation

Setup

Serde and JSON serialization:

Enabled by default with the serde-all feature.

Cargo.toml:

[dependencies]
anterofit = "0.1"
# `serde` is required in the dependencies but not in the crate root.
serde = "0.9"
serde_derive = "0.9"

Crate Root:

#[macro_use] extern crate anterofit;
#[macro_use] extern crate serde_derive;

rustc-serialize:

Cargo.toml:

[dependencies]
rustc-serialize = "0.3"

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

Crate Root:

#[macro_use] extern crate anterofit;
extern crate rustc_serialize;

License

Licensed under either of

at your option.

Contribution

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.

More Repositories

1

img_hash

A Rust library for calculating perceptual hash values of images
Rust
314
star
2

multipart

A backend-agnostic extension for file uploads in HTTP libraries for Rust
Rust
190
star
3

mime_guess

MIME type guessing of file extensions for Rust.
Rust
155
star
4

multipart-async

Multipart requests with an asynchronous API.
Rust
72
star
5

img-dup

A tool for finding duplicate and similar images, written in Rust
Rust
55
star
6

buf_redux

A drop-in replacement for Rust's std::io::BufReader, with extra features
Rust
39
star
7

readme-doctest-poc

Automatically test Rust code examples in your README
Rust
21
star
8

const-cstr

Create static C-compatible strings from Rust string literals.
Rust
16
star
9

ferrite

Predecessor to Anterofit (https://github.com/abonander/anterofit)
Rust
13
star
10

safemem

Safe wrappers for `memmove`, `memset`, etc. in Rust
Rust
11
star
11

rawr

Reddit API Wrapper for Rust. HTTP-client-agnostic.
Rust
8
star
12

wingui

A safe Rust wrapper for the Windows GUI
Rust
7
star
13

vec-vp-tree

A vantage-pont-tree backed by a contiguous `Vec` for better data locality.
Rust
4
star
14

rust-what-now

A newbie's field guide to contributing to the Rust ecosystem.
4
star
15

fontconfig-rs

A wrapper around freedesktop's fontconfig utility, for locating fontfiles on a Linux-based system. Requires libfontconfig to be installed.
Rust
4
star
16

file_dialog

A file dialog in Rust using Conrod
Rust
3
star
17

mvp-tree-rs

A multi-vantage point (MVP) tree for Rust.
Rust
2
star
18

thread-stack

A concurrent stack datastructure for Rust which uses a thread's stack as the backing storage.
Rust
1
star
19

better_unwraps

Rust
1
star
20

dbl-buf

Generic double-buffer for Rust
Rust
1
star
21

img-hash-extern

Rust
1
star
22

async-mlock-poc

Rust
1
star
23

display_bytes

Rust
1
star
24

py-emulatorlib

A Python 3 wrapper for the telnet commands exposed by the Android emulator.
1
star