3 min read4 days ago
–
Press enter or click to view image in full size
What is deboa-macros?
deboa-macros is a procedural-macro crate for Rust that builds on top of the core HTTP client deboa. Its goal is to simplify common HTTP request patterns using expressive macros—turning verbose boilerplate into concise, type-safe code.
Where deboa provides low-level HTTP capabilities (HTTP/1 + HTTP/2, async runtimes like Tokio or Smol, etc.), deboa-macros layers ergonomic syntax on top so you can focus on logic instead of
request-building ceremony.
Why Macros? — — The Case for deboa-macros
Rust’s procedural macros allow developers to run code at compile time to generate boilerplate, enforce patterns, and create domain-specific syntax.
For HTTP requests, muc…
3 min read4 days ago
–
Press enter or click to view image in full size
What is deboa-macros?
deboa-macros is a procedural-macro crate for Rust that builds on top of the core HTTP client deboa. Its goal is to simplify common HTTP request patterns using expressive macros—turning verbose boilerplate into concise, type-safe code.
Where deboa provides low-level HTTP capabilities (HTTP/1 + HTTP/2, async runtimes like Tokio or Smol, etc.), deboa-macros layers ergonomic syntax on top so you can focus on logic instead of
request-building ceremony.
Why Macros? — — The Case for deboa-macros
Rust’s procedural macros allow developers to run code at compile time to generate boilerplate, enforce patterns, and create domain-specific syntax.
For HTTP requests, much of the code is repetitive:
- building the request
- serializing bodies
- deserializing responses
- handling errors
deboa-macros addresses these pain points with:
- Compile-time type safety for request/response bodies (via Serde)
- Async/await support
- Declarative API client definitions using the
#[bora]attribute macro
The result is a more pleasant, readable workflow — -without sacrificing control or safety.
Update
Starting from deboa-macros 0.0.7, bora macro won’t be available on this crate anymore. It has been moved to vamo-macros crate.
Key Features & API Overview
✔ Function-like Macros
deboa-macros provides macros corresponding to HTTP verbs:
Each macro expands into an async HTTP call using deboa, with optional body and response type handling.
✔ #[bora] Attribute Macro
The bora macro lets you define a high-level API client declaratively.
You describe:
- the endpoints
- their HTTP methods
- input parameters
- response bodies
- serialization format
The macro generates a fully-typed client struct with async methods.
✔ Serialization Formats Supported
All wired through Serde.
Example: GET Request Using get!
use deboa::Deboa;use deboa_extras::http::serde::json::JsonBody;#[derive(serde::Deserialize)]struct Post { id: u32, title: String, body: String, userId: u32,}#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let mut client = Deboa::new(); let post: Post = get!( "https://jsonplaceholder.typicode.com/posts/1", &mut client, JsonBody, Post ); println!("Post title: {}", post.title); Ok(())}
Example: Declarative API Client with #[bora]
use deboa::errors::DeboaError;use deboa_macros::bora;use vamo::Vamo;#[derive(Deserialize, Debug)]pub struct Post { pub id: u32, pub title: String,}#[bora( api( get(name="get_by_id", path="/posts/<id:i32>", res_body=Post, format="json") ))]pub struct PostService;#[tokio::main]async fn main() -> Result<(), DeboaError> { let client = Vamo::new("https://jsonplaceholder.typicode.com"); let mut service = PostService::new(client); let post = service.get_by_id(1).await?; println!("id: {}", post.id); println!("title: {}", post.title); Ok(())}
When to Use deboa-macros
Great Fit When:
- You want concise, readable HTTP calls.
- You prefer declarative API client definitions.
- You care about type-safe request/response handling.
- You’re working with async Rust.
Consider Using Raw deboa When:
- You need very fine-grained control over request lifecycle.
- You need complex middleware or streaming.
- You prefer explicit, hand-written code over macro-generated abstractions.
Ecosystem Fit
deboa-macros sits on top of a trio of crates:
**deboa**— core HTTP client**deboa-extras**— additional serialization/compression helpers, websockets, sse and custom middleware (catchers).**deboa-macros**— ergonomic macros and declarative API definitions
This combination forms a flexible stack for building REST clients in Rust with minimal boilerplate.
My Take
As a developer, libraries that reduce boilerplate without hiding
important details are always welcome. deboa-macros hits that sweet spot:
- It speeds up API client creation
- It preserves strong typing
- It works seamlessly with Rust async and Serde
- You can still drop down to raw
deboafor advanced behavior
If you’re building internal tools, microservices, or interacting with REST APIs, deboa-macros is definitely worth trying.
Conclusion
deboa-macros brings ergonomic macros, type safety, and readability to HTTP client code in Rust. It builds on deboa’s solid async foundation to provide high-level, expressive syntax ideal for REST-heavy applications.
If you enjoy clean, declarative Rust with less boilerplate — -and still want full control when needed — -this crate is a strong choice.