Type-safe and enum style API for Rust, some benefits:
- It abstracts away repetitive boilerplate code like url formatting, query / header encoding and response deserialization.
- Type-safe endpoints, readable like a spec, easy to add new or refactor existing endpoints.
- Async by default and lightweight JSON-RPC support.
Features:
- Type-safe and enum style HTTP API
- JSON-RPC with batching support (default feature)
- Optional middleware support via
reqwest-middleware(using themiddlewarefeature) - Flexible request customization via closures
cargo add reqwest-enum or add it to your Cargo.toml:
[dependencies]
reqwest-enum = "0.4.0"jsonrpc: (Enabled by default) Provides support for JSON-RPC requests, including batching. Requiresfutures.middleware: Enables integration withreqwest-middleware, allowing you to use custom middleware with your requests. This changes the underlyingRequestBuildertype used by theProvidertoreqwest_middleware::RequestBuilder.
- Define endpoints for https://httbin.org as an enum:
pub enum HttpBin {
Get,
Post,
Bearer,
}- Implement
Targetfor the enum:
// Simplified trait definition for illustration. Refer to src/target.rs for the full definition.
pub trait Target {
fn base_url(&self) -> Cow<'_, str>; // Can be dynamic
fn method(&self) -> HTTPMethod;
fn path(&self) -> String;
fn query(&self) -> HashMap<String, String>; // Key/Value for query parameters
fn headers(&self) -> HashMap<String, String>; // Key/Value for headers
fn authentication(&self) -> Option<AuthMethod>; // Optional authentication
fn body(&self) -> Result<HTTPBody, Error>; // Request body, can be fallible
// Note: Timeout is now handled by the Provider or individual request builders, not directly in Target.
}- Create a provider and request:
let provider = Provider::<HttpBin>::default();
let response = provider.request(HttpBin::Get).await.unwrap();
assert_eq!(response.status(), 200);The Provider offers powerful customization through closures passed to Provider::new:
EndpointFn:fn(target: &T) -> String- Allows you to dynamically determine the complete request URL based on the
targetenum variant. This overrides the default behavior of combiningbase_url()andpath().
- Allows you to dynamically determine the complete request URL based on the
RequestBuilderFn:Box<dyn Fn(&ProviderRequestBuilder, &T) -> ProviderRequestBuilder + Send + Sync>- Provides a way to modify the
ProviderRequestBuilderafter it has been initially constructed by theProviderbut before the request is sent. This is useful for:- Adding or modifying headers.
- Changing request parameters or body.
- Any other final adjustments to the request, especially useful when interacting with middleware if the
middlewarefeature is enabled.
- Provides a way to modify the
The ProviderRequestBuilder type alias is used internally and in RequestBuilderFn to ensure type compatibility whether you are using reqwest::RequestBuilder (default) or reqwest_middleware::RequestBuilder (with the middleware feature).
Full example can be found in examples/ethereum-rpc.
- Define Ethereum JSON-RPC methods as an enum:
pub enum EthereumRPC {
ChainId,
GasPrice,
BlockNumber,
GetBalance(&'static str),
GetBlockByNumber(&'static str, bool),
GetTransactionCount(&'static str, BlockParameter),
Call(TransactionObject, BlockParameter),
EstimateGas(TransactionObject),
SendRawTransaction(&'static str),
}- Implement
TargetandJsonRpcTargerfor the enum:
pub trait JsonRpcTarget: Target {
fn method_name(&self) -> &'static str;
fn params(&self) -> Vec<Value>;
}- Create a provider and request:
let provider = Provider::<EthereumRPC>::default();
let response: JsonRpcResponse<String> =
provider.request_json(EthereumRPC::ChainId).await.unwrap();
assert_eq!(response.result, "0x1");MIT or Apache-2.0