Skip to main content

Crate better_fetch

Crate better_fetch 

Source
Expand description

§better-fetch

Typed HTTP client layer on top of reqwest, inspired by @better-fetch/fetch. This crate is not affiliated with the upstream TypeScript project.

§Quick flow

  1. Create a Client (or ClientBuilder) with a base URL.
  2. Start a request with Client::get / Client::post (flexible RequestBuilder) or Client::call (typed Endpoint routes).
  3. Configure path params, query, body, auth, retries on the builder.
  4. Execute with RequestBuilder::send (buffered Response), RequestBuilder::send_stream (incremental StreamingResponse), send_json, or EndpointRequestBuilder::send_json.

§Buffered vs streaming

Use .get() when you want string paths and a typed JSON response (send_json::<T>()). Use Client::call when method, path, params, query, and response are bound to an Endpoint type.

§Cargo features

The client always uses reqwest as the default HTTP backend. Enable crate features to turn on reqwest capabilities and optional APIs.

FeatureDescription
json (default)JSON bodies, send_json, custom JsonParserFn
rustls-tls (default)TLS via rustls (enable native-tls instead, not both)
native-tlsTLS via the platform stack (do not combine with rustls-tls)
multipartRequestBuilder::multipart
towerTower transport stack via ClientBuilder::transport_stack (implies rustls-tls)
schemaSchemaRegistry route metadata
openapiOpenAPI 3.0 export from schema registry
validateGarde validation on JSON request/response bodies
schema-validateRuntime JSON Schema validation (strict registry: request/response body, query, params)
mietteDiagnosticError for labeled error reports
otelopentelemetry, opentelemetry_sdk, tracing_opentelemetry re-exports
blocking, cookiesPassed through to reqwest
sseSSE (text/event-stream) helpers on StreamingResponse
macros#[derive(Endpoint)], EndpointParamsDerive, EndpointQueryDerive
fullCommon optional features bundled for internal apps

See the repository README for full examples.

§Example (.get() — flexible path, typed response)

let client = Client::new("https://jsonplaceholder.typicode.com")?;

// send() returns Response for any status; json() fails on non-2xx
let todo: Todo = client
    .get("/todos/:id")
    .param("id", 1)
    .send()
    .await?
    .json()
    .await?;

// Or in one step:
let todo: Todo = client.get("/todos/:id").param("id", 1).send_json().await?;

§Example (typed endpoint — method, path, params, response)

define_params!(GetTodoParams for "/todos/:id" { id: u64 });

struct GetTodo;
impl Endpoint for GetTodo {
    const METHOD: Method = Method::GET;
    const PATH: &'static str = "/todos/:id";
    type Response = Todo;
    type Params = GetTodoParams;
    type Query = ();
    type Body = ();
    type Headers = ();
}

let client = Client::new("https://jsonplaceholder.typicode.com")?;
let todo = client
    .call::<GetTodo>()
    .params(GetTodoParams { id: 1 })
    .send_json()
    .await?;

Re-exports§

pub use api_response::into_api_result;json
pub use api_response::ApiResponseExt;json
pub use auth::AsyncTokenProvider;
pub use auth::Auth;
pub use auth::TokenSource;
pub use backend::HttpBackend;
pub use backend::HttpBody;
pub use backend::HttpRequest;
pub use backend::HttpResponse;
pub use backend::HttpStreamingResponse;
pub use backend::RecordedBodyKind;
pub use backend::RecordedRequest;
pub use backend::RecordingBackend;
pub use backend::ReqwestBackend;
pub use client::Client;
pub use client::ClientBuilder;
pub use client::ClientConfig;
pub use endpoint::DefaultParamsInitial;
pub use endpoint::Endpoint;
pub use endpoint::EndpointBody;
pub use endpoint::EndpointHeaders;
pub use endpoint::EndpointParams;
pub use endpoint::EndpointParamsInitial;
pub use endpoint::EndpointQuery;
pub use endpoint::EndpointRequestBuilder;
pub use endpoint::NeedsBody;
pub use endpoint::NeedsParams;
pub use endpoint::ParamsBuilderState;
pub use endpoint::Ready;
pub use error::Error;
pub use error::TransportKind;
pub use hooks::ErrorContext;
pub use hooks::Hooks;
pub use hooks::RequestContext;
pub use hooks::ResponseContext;
pub use hooks::StreamingResponseContext;
pub use hooks::StreamingResponseMeta;
pub use hooks::StreamingSuccessContext;
pub use hooks::SuccessContext;
pub use plugin::Plugin;
pub use plugin::PluginRegistry;
pub use plugin::PreparedRequest;
pub use plugins::LoggerPlugin;
pub use request::RequestBuilder;
pub use response::Response;
pub use response::ResponseBodyKind;
pub use retry::default_should_retry;
pub use retry::parse_retry_after;
pub use retry::RetryPolicy;
pub use retry::ShouldRetryFn;
pub use schema::EndpointSchema;schema
pub use schema::SchemaRegistry;schema
pub use sse::parse_sse_events;sse
pub use sse::SseDecoder;sse
pub use sse::SseEvent;sse
pub use sse::SseEventStream;sse
pub use streaming::BodyStream;
pub use streaming::StreamingResponse;
pub use openapi::OpenApiBuilder;openapi
pub use openapi::OpenApiComponents;openapi
pub use openapi::OpenApiDocument;openapi
pub use openapi::OpenApiInfo;openapi
pub use openapi::OpenApiOperation;openapi
pub use openapi::OpenApiSchemaRef;openapi
pub use openapi::OpenApiServer;openapi
pub use tower::BoxHttpService;tower
pub use tower::BoxStreamingHttpService;tower
pub use tower::ReqwestHttpService;tower
pub use tower::ReqwestStreamingHttpService;tower
pub use tower::ServiceBackend;tower
pub use miette_diagnostic::DiagnosticError;miette
pub use otel::opentelemetry;otel
pub use otel::opentelemetry_sdk;otel
pub use otel::tracing_opentelemetry;otel

Modules§

api_response
Helpers for typed success vs error response bodies.
auth
Authentication for clients and individual requests.
backend
HTTP transport abstraction.
cancel
Request cancellation (CancellationToken) compatible with cooperative async abort.
client
HTTP client, builder, and shared configuration.
endpoint
Typed API routes via the Endpoint trait.
error
Error types and helpers for HTTP, transport, hooks, and retries.
hooks
Lifecycle hooks for requests and responses.
miette_diagnosticmiette
Rich diagnostics for Error when the miette feature is enabled.
multipartmultipart
Re-export of reqwest multipart types (feature multipart). multipart/form-data
openapiopenapi
OpenAPI 3.0 document builder (requires openapi feature).
otelotel
OpenTelemetry re-exports when the otel feature is enabled.
plugin
Plugin hooks run after URL construction and auth, before request lifecycle hooks.
plugins
Built-in plugins.
prelude
Convenient re-exports for application code.
request
Per-request fluent builder.
response
HTTP response wrapper with a fully buffered body.
retry
Retry policies for transport and HTTP failures.
schemaschema
Schema registry for endpoint metadata (requires schema feature).
schema_validateschema-validate
Runtime JSON Schema validation against a SchemaRegistry.
ssesse
Server-Sent Events (text/event-stream) helpers for StreamingResponse.
streaming
Streaming HTTP responses (send_stream).
towertower
Tower transport integration (tower feature).

Macros§

define_params
Defines path parameters for a route and implements EndpointParams.
endpoint
Defines a simple Endpoint with optional typed params and query.
impl_serde_endpoint_queryjson
Implements EndpointQuery for a serde-serializable query struct (feature json).

Structs§

CancellationToken
A token which can be used to signal a cancellation request to one or more tasks.

Enums§

QueryValue
Query parameter value (scalar or repeated).

Functions§

json_parserjson
Wraps a custom JSON parse function for use with ClientBuilder::json_parser.
path_param_names
Returns :param segment names in left-to-right path order (ignores an embedded ?query).
serde_json_parserjson
Default parser using serde_json::from_slice (same semantics as the fast path, as a JsonParserFn).

Type Aliases§

JsonParserFnjson
Parses response bytes into serde_json::Value before deserializing to T.
Result
Result alias using Error.

Derive Macros§

EndpointDerivemacros
Derives Endpoint.
EndpointParamsDerivemacros
Derives EndpointParams for a struct with one field per :param segment in #[endpoint(path = "...")].
EndpointQueryDerivemacros
Derives EndpointQuery for a serde-serializable query struct.