Crate vamo

Crate vamo 

Source
Expand description

§Vamo: A High-Level HTTP Client for Deboa

vamo provides an ergonomic, high-level API on top of the deboa HTTP client, making it easier to work with RESTful APIs and other HTTP services. It offers a more intuitive interface for building and sending HTTP requests while maintaining full compatibility with the underlying deboa client.

§Features

  • Fluent API: Chainable methods for building and sending requests
  • Resource-Oriented: First-class support for REST resources with the Resource trait
  • Authentication: Built-in support for common authentication methods
  • Type Safety: Strong typing for request/response bodies
  • Flexible: Works with any HTTP method and content type
  • Async by Default: Built on top of async/await for high performance

§Getting Started

Add vamo and its dependencies to your Cargo.toml:

[dependencies]
vamo = { version = "0.1", path = "../vamo" }
deboa = { version = "0.1", path = ".." }
deboa-extras = { version = "0.1", path = "../deboa-extras" }
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }

§Basic Usage

§Making Simple Requests

use vamo::Vamo;
use deboa_extras::http::serde::json::JsonBody;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create a new Vamo client with a base URL
    let mut vamo = Vamo::new("https://api.example.com")?;

    // Make a GET request
    let response = vamo
        .get("/users/1")?
        .send()
        .await?;
     
    // Parse response as JSON
    let user: User = response.body_as(JsonBody).await?;
    println!("User: {:?}", user);

    // Make a POST request with JSON body
    let new_user = json!({
        "name": "John Doe",
        "email": "john@example.com"
    });
     
    let response = vamo
        .post("/users")?
        .body_as(JsonBody, &new_user)?
        .send()
        .await?;
     
    println!("Created user: {:?}", response.status());
    Ok(())
}

§Working with Resources

Vamo provides a Resource trait that makes it easy to work with REST resources:

use vamo::{Vamo, resource::{Resource, ResourceMethod}};
use deboa_extras::http::serde::json::JsonBody;
use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize)]
struct User {
    id: Option<u64>,
    name: String,
    email: String,
}

impl Resource for User {
    // Return the resource ID as a string
    fn id(&self) -> String {
        self.id.map(|id| id.to_string()).unwrap_or_default()
    }
     
    // Return the base path for this resource (e.g., "users")
    fn name(&self) -> &str {
        "users"
    }
     
    // Specify how to serialize this resource
    fn body_type(&self) -> impl deboa::client::serde::RequestBody {
        JsonBody
    }
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut vamo = Vamo::new("https://api.example.com")?;
     
    // List all users
    let mut user_template = User {
        id: None,
        name: String::new(),
        email: String::new(),
    };
     
    let users: Vec<User> = vamo
       .load(&mut user_template)?
       .send()
       .await?
       .body_as(JsonBody)
       .await?;
    println!("All users: {:?}", users);
     
    // Create a new user
    let mut new_user = User {
        id: None,
        name: "John Doe".to_string(),
        email: "john@example.com".to_string(),
    };
     
    let created: User = vamo
       .create(&mut new_user)?
       .send()
       .await?
       .body_as(JsonBody)
       .await?;
    println!("Created user: {:?}", created);
     
    // Update a user
    let mut updated_user = User {
        id: created.id,
        name: "John Updated".to_string(),
        email: created.email,
    };
     
    let updated: User = vamo
       .update(&mut updated_user)?
       .send()
       .await?
       .body_as(JsonBody)
       .await?;
    println!("Updated user: {:?}", updated);
     
    // Delete a user
    vamo.remove(&mut updated_user)?.send().await?;
    println!("User deleted");
     
    Ok(())
}

§Authentication

Vamo provides convenience methods for common authentication methods:

// Bearer token authentication
let mut vamo = Vamo::new("https://api.example.com")?;
vamo
  .get("/users/1")
  .bearer_auth("your-token-here")
  .send()
  .await?;

// Basic authentication
let mut vamo = Vamo::new("https://api.example.com")?;
vamo
  .get("/users/1")
  .basic_auth("username", "password")
  .send()
  .await?;

§Error Handling

Vamo uses the deboa::Result type for error handling, which provides detailed error information including:

  • Network errors
  • Serialization/deserialization errors
  • HTTP protocol errors
  • URL parsing errors

§Examples

Check the examples/ directory for more comprehensive examples of using Vamo with different types of APIs and authentication methods.

§License

MIT license

§Author

Rogerio Pacheco rogerio.pacheco@gmail.com

Modules§

resource
Resource Module

Structs§

Vamo
A builder for HTTP requests.