| Crates.io | reqwest-builder-derive |
| lib.rs | reqwest-builder-derive |
| version | 0.1.2 |
| created_at | 2025-07-02 14:41:12.553764+00 |
| updated_at | 2025-07-02 17:54:15.649824+00 |
| description | Derive macros for reqwest-builder |
| homepage | |
| repository | https://github.com/FrostPrice/reqwest-builder/tree/main/reqwest-builder-derive |
| max_upload_size | |
| id | 1735204 |
| size | 24,205 |
A derive macro for the reqwest-builder crate that automatically generates IntoReqwestBuilder implementations for your structs.
This crate provides the IntoReqwestBuilder derive macro that automatically implements the trait for your request structs, eliminating the need for manual implementation. Simply annotate your struct with attributes to define HTTP request properties.
IntoReqwestBuilder trait automaticallyAdd this to your Cargo.toml:
[dependencies]
reqwest-builder = { version = "0.2.0", features = ["derive"] }
serde = { version = "1.0", features = ["derive"] }
use reqwest_builder::{IntoReqwestBuilder, RequestBody};
use reqwest_builder_derive::IntoReqwestBuilder;
use serde::Serialize;
#[derive(Serialize, IntoReqwestBuilder)]
#[request(method = "GET", path = "/users/{id}")]
struct GetUserRequest {
#[path_param]
id: u64,
#[query]
include_posts: Option<bool>,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let client = reqwest_middleware::ClientBuilder::new(reqwest::Client::new()).build();
let base_url = url::Url::parse("https://api.example.com")?;
let request = GetUserRequest {
id: 123,
include_posts: Some(true),
};
let builder = request.into_reqwest_builder(&client, &base_url)?;
let response = builder.send().await?;
println!("Status: {}", response.status());
Ok(())
}
These attributes are applied to the struct itself:
#[request(method = "...")] (Required)Specifies the HTTP method for the request.
Supported methods:
GETPOSTPUTDELETEPATCHHEADOPTIONS#[derive(Serialize, IntoReqwestBuilder)]
#[request(method = "POST", path = "/users")]
struct CreateUserRequest {
// ...
}
#[request(path = "...")] (Required)Specifies the endpoint path. Can include placeholders for path parameters.
#[derive(Serialize, IntoReqwestBuilder)]
#[request(method = "GET", path = "/users/{id}/posts/{post_id}")]
struct GetPostRequest {
#[path_param]
id: u64,
#[path_param]
post_id: u64,
}
#[request(body = "...")] (Optional)Specifies how the request body should be encoded. Defaults to "json".
Supported body types:
"json" - JSON encoding (default)"form" - Form URL encoding"multipart" - Multipart form data"none" - No request body#[derive(Serialize, IntoReqwestBuilder)]
#[request(method = "POST", path = "/login", body = "form")]
struct LoginRequest {
username: String,
password: String,
}
These attributes are applied to individual struct fields:
#[path_param]Marks a field as a path parameter. The field's value will replace {field_name} in the path.
#[derive(Serialize, IntoReqwestBuilder)]
#[request(method = "GET", path = "/users/{user_id}/posts/{id}")]
struct GetPostRequest {
#[path_param]
user_id: u64,
#[path_param]
id: u64,
}
#[query] and #[query(name = "...")]Marks a field as a query parameter.
#[derive(Serialize, IntoReqwestBuilder)]
#[request(method = "GET", path = "/posts")]
struct ListPostsRequest {
#[query]
page: Option<u32>,
#[query(name = "per_page")]
limit: Option<u32>,
#[query]
published: Option<bool>,
}
This generates a URL like: /posts?page=1&per_page=10&published=true
#[header] and #[header(name = "...")]Marks a field as a request header.
#[derive(Serialize, IntoReqwestBuilder)]
#[request(method = "POST", path = "/api/data")]
struct ApiRequest {
#[header(name = "Authorization")]
auth_token: String,
#[header(name = "Content-Type")]
content_type: String,
#[header]
user_agent: String, // Uses field name as header name
// Body fields
data: String,
}
#[body]Explicitly marks a field to be included in the request body. This is the default behavior for unmarked fields, so it's usually not necessary.
#[derive(Serialize, IntoReqwestBuilder)]
#[request(method = "POST", path = "/users")]
struct CreateUserRequest {
#[header(name = "Authorization")]
auth_token: String,
#[body] // Explicit, but not necessary
name: String,
email: String, // Implicitly included in body
}
#[derive(Serialize, IntoReqwestBuilder)]
#[request(method = "POST", path = "/users/{id}/posts", body = "json")]
struct CreatePostRequest {
// Path parameter
#[path_param]
id: u64,
// Query parameters
#[query]
draft: Option<bool>,
#[query(name = "notify_followers")]
should_notify: Option<bool>,
// Headers
#[header(name = "Authorization")]
auth_token: String,
#[header(name = "Content-Type")]
content_type: String,
#[header(name = "X-Client-Version")]
client_version: String,
// Request body fields
title: String,
content: String,
tags: Vec<String>,
metadata: serde_json::Value,
}
#[derive(Serialize, IntoReqwestBuilder)]
#[request(method = "POST", path = "/auth/login", body = "form")]
struct LoginRequest {
#[header(name = "User-Agent")]
user_agent: String,
username: String,
password: String,
remember_me: Option<bool>,
}
#[derive(Serialize, IntoReqwestBuilder)]
#[request(method = "GET", path = "/search", body = "none")]
struct SearchRequest {
#[query]
q: String,
#[query]
page: Option<u32>,
#[query(name = "sort_by")]
sort: Option<String>,
#[header(name = "Accept")]
accept: String,
}
The derive macro works with various Rust types:
String, u32, i64, bool, etc.Option<T> for optional query parameters and headersVec<T>, HashMap<K, V> (in body)Serialize (for body fields)The generated implementation works with error handling approach provided by reqwest-builder:
// Explicit error handling
match request.into_reqwest_builder(&client, &base_url) {
Ok(builder) => {
let response = builder.send().await?;
// Handle response
}
Err(e) => {
eprintln!("Request building failed: {}", e);
}
}
The derive macro generates:
Headers struct for typed header managementIntoReqwestBuilder trait methods:
method() - Returns the HTTP methodendpoint() - Builds the URL with path parameter substitutionheaders() - Creates headers from annotated fieldsquery_params() - Builds query parameters from annotated fieldsbody() - Specifies the body encoding typeserde with derive feature for serializationreqwest-builder as the main crateThis project is licensed under the MIT License - see the LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.