Hi All!
I think, that it would be very useful to implement tower::Service trait for cyper::Client:
impl tower::Service<http::Request<cyper::Body>> for cyper::Client {
type Response = http::Response<cyper::Body>;
/// ...
}
That would allow using cyper with the whole Tower middleware ecosystem (tower::ServiceBuilder, tower-http layers: retries, timeouts, rate limits, tracing, auth, etc.).
Also, I maintain a crate tower-http-client that turns any tower::Service<http::Request<B>> into a backend-agnostic HTTP client.
Here is the main part of example:
#[derive(Debug, Deserialize)]
struct IpInfo {
ip: String,
country: String,
}
#[tokio::main]
async fn main() -> Result<(), BoxError> {
eprintln!("-> Creating an HTTP client with Tower layers...");
// First of all, we create an opaque client using the reqwest client.
let opaque_client = into_tower_http_client(reqwest::Client::new());
// Secondary we add some middleware to the client and then box it.
let mut client: HttpClient = ServiceBuilder::new()
.layer_fn(BoxCloneSyncService::new)
.map_request(|mut request: http::Request<_>| {
request
.headers_mut()
.typed_insert(UserAgent::from_static("tower-http-client"));
request
})
.service(opaque_client);
// Finally, we can use the boxed client to send requests.
eprintln!("-> Getting IP information...");
let response = client.get("http://api.myip.com").send().await?;
let info = response.body_reader().json::<IpInfo>().await?;
eprintln!("-> Got information:");
eprintln!(" IP address: {}", info.ip);
eprintln!(" Country: {}", info.country);
Ok(())
}
So exposing Service would make cyper instantly compatible with that model. Happy to help with a PR if this direction looks reasonable.
Hi All!
I think, that it would be very useful to implement
tower::Servicetrait forcyper::Client:That would allow using cyper with the whole Tower middleware ecosystem (tower::ServiceBuilder, tower-http layers: retries, timeouts, rate limits, tracing, auth, etc.).
Also, I maintain a crate
tower-http-clientthat turns anytower::Service<http::Request<B>>into a backend-agnostic HTTP client.Here is the main part of example:
So exposing Service would make cyper instantly compatible with that model. Happy to help with a PR if this direction looks reasonable.