Canapi

Common Canapi traits.

Canapi is a collection of Rust crate to make it possible to share a REST API definition between clients and servers. You define your endpoints (Endpoint trait), bind them to your databse (Provider trait), and you can re-use these endpoints in your client (Fetch trait).

This requires three separate crates: one for your API defintion, one for your server, and one for the client.

Example

my-api, where you define the API.

```rust use canapi::Endpoint;

[derive(Default, Serialize, Deserialize)]

struct UserEndpoint { id: Option, name: Option, bio: Option, }

impl Endpoint for PostEndpoint { type Id = i32;

fn endpoint() -> &'static str {
    "/api/v1/users"
}

} ```

my-server, to bind endpoints to database (and expose them to the rest of the world)

```rust use canapi::Provider; use diesel::*; // Example with Diesel use my_api::UserEndpoint;

/// Define the User model…

impl Provider for User { type Data = UserEndpoint;

fn get(conn: &PgConnection, id: i32) -> Option<Post> {
    posts::table.filter(posts::id.eq(id))
        .limit(1)
        .get_result::<Post>(conn)
        .ok()
}

}

// Use rocket, actix-web, iron, gotham or whatever you want to expose your endpoints… ```

my-client, to use your API (here with a potential WASM Fetch impl)

```rust use canapiwasm::WasmFetch; use plumeapi;

[derive(Default)]

pub struct Api { users: UserEndpoint }

fn fetchfirstpost() { let api = Api::default(); let post = api.users.get::(1); assert_eq(post.id, Some(1)); }

fn findhello() { let api = Api::default(); let post = api.users.find::(PostEndpoint { name: Some(String::new("Jane")), ..PostEndpoint::default() }); asserteq!(post.title, Some(String::new("Jane"))); } ```