Http Clients
In The "🗼 Services all the way down 🐢" chapter you can read and learn that a big pillar of Rama's architecture is build on top of the Service
concept. A Service
takes as input a user-defined State
(e.g. containing your database Pool) and a Request
, and uses it to serve either a Response
or Error
. Such a Service
can produce the response "directly" (also called ☘️ Leaf services) or instead pass the request and state to an inner Service
which it wraps around (so called 🍔 Middlewares).
It's a powerful concept, originally introduced to Rust by the Tower ecosystem and allows you build complex stacks specialised to your needs in a modular and easy manner. Even cooler is that this works for both clients and servers alike.
Rama provides an HttpClient
which sends your Http Request
over the network and returns the Response
if it receives and read one or an Error
otherwise. Combined with the many Layers (middleware) that Rama
provides and perhaps also some developed by you it is possible to create a powerful Http client suited to your needs.
As a 🍒 cherry on the cake you can import the HttpClientExt
trait in your Rust module to be able to use your Http Client Service
stack using a high level API to build and send requests with ease.
Http Client Example
The full "high level" example can be found at https://github.com/plabayo/rama/tree/main/examples/http_high_level_client.rs.
#![allow(unused)] fn main() { use rama::http::service::client::HttpClientExt; let client = ( TraceLayer::new_for_http(), DecompressionLayer::new(), AddAuthorizationLayer::basic("john", "123") .as_sensitive(true) .if_not_present(), RetryLayer::new( ManagedPolicy::default().with_backoff(ExponentialBackoff::default()), ) .layer(HttpClient::default()); #[derive(Debug, Deserialize)] struct Info { name: String, example: String, magic: u64, } let info: Info = client .get("http://example.com/info") .header("x-magic", "42") .typed_header(Accept::json()) .send(Context::default()) .await .unwrap() .try_into_json() .await .unwrap(); }