Skip to main content

ServiceExt

Trait ServiceExt 

Source
pub trait ServiceExt<ReqBody, RespBody, Err>: Sized {
    // Required method
    fn execute<R>(
        &mut self,
        request: Request<R>,
    ) -> impl Future<Output = Result<Response<RespBody>, Err>>
       where ReqBody: From<R>;

    // Provided methods
    fn request<U>(
        &mut self,
        method: Method,
        uri: U,
    ) -> ClientRequestBuilder<'_, Self, Err, RespBody>
       where U: IntoUri,
             Uri: TryFrom<U::TryInto>,
             <Uri as TryFrom<U::TryInto>>::Error: Into<Error> { ... }
    fn get<U>(
        &mut self,
        uri: U,
    ) -> ClientRequestBuilder<'_, Self, Err, RespBody>
       where U: IntoUri,
             Uri: TryFrom<U::TryInto>,
             <Uri as TryFrom<U::TryInto>>::Error: Into<Error> { ... }
    fn put<U>(
        &mut self,
        uri: U,
    ) -> ClientRequestBuilder<'_, Self, Err, RespBody>
       where U: IntoUri,
             Uri: TryFrom<U::TryInto>,
             <Uri as TryFrom<U::TryInto>>::Error: Into<Error> { ... }
    fn post<U>(
        &mut self,
        uri: U,
    ) -> ClientRequestBuilder<'_, Self, Err, RespBody>
       where U: IntoUri,
             Uri: TryFrom<U::TryInto>,
             <Uri as TryFrom<U::TryInto>>::Error: Into<Error> { ... }
    fn patch<U>(
        &mut self,
        uri: U,
    ) -> ClientRequestBuilder<'_, Self, Err, RespBody>
       where U: IntoUri,
             Uri: TryFrom<U::TryInto>,
             <Uri as TryFrom<U::TryInto>>::Error: Into<Error> { ... }
    fn delete<U>(
        &mut self,
        uri: U,
    ) -> ClientRequestBuilder<'_, Self, Err, RespBody>
       where U: IntoUri,
             Uri: TryFrom<U::TryInto>,
             <Uri as TryFrom<U::TryInto>>::Error: Into<Error> { ... }
    fn head<U>(
        &mut self,
        uri: U,
    ) -> ClientRequestBuilder<'_, Self, Err, RespBody>
       where U: IntoUri,
             Uri: TryFrom<U::TryInto>,
             <Uri as TryFrom<U::TryInto>>::Error: Into<Error> { ... }
}
Expand description

An extension trait for Tower HTTP services with the typical client methods.

Essentially, this trait adds methods similar to those in reqwest::Client one.

§Examples

Creating a client and reading the response body using this trait.

use http::{header::USER_AGENT, HeaderValue};
use tower::{ServiceBuilder, ServiceExt};
use tower_http::ServiceBuilderExt;
use tower_http_client::{ServiceExt as _, ResponseExt as _};
use tower_reqwest::HttpClientLayer;
use wiremock::{Mock, MockServer, ResponseTemplate, matchers::{method, path}};

/// Implementation agnostic HTTP client.
type HttpClient = tower::util::BoxCloneService<
    http::Request<reqwest::Body>,
    http::Response<reqwest::Body>,
    anyhow::Error,
>;

/// Creates HTTP client with Tower layers on top of the given client.
fn make_client(client: reqwest::Client) -> HttpClient {
    ServiceBuilder::new()
        // Add some layers.
        .override_request_header(USER_AGENT, HeaderValue::from_static("tower-http-client"))
        // Convert a generic body type into `reqwest::Body`.
        .map_request_body(reqwest::Body::wrap)
        // Make client compatible with the `tower-http` layers.
        .layer(HttpClientLayer)
        .service(client)
        .map_err(anyhow::Error::from)
        .boxed_clone()
}

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // Start a mock server for testing
    let mock_server = MockServer::start().await;
    
    // Configure mock response
    Mock::given(method("GET"))
        .and(path("/hello"))
        .respond_with(ResponseTemplate::new(200).set_body_string("Hello, World!"))
        .mount(&mock_server)
        .await;

    // Create a new client.
    let mut client = make_client(reqwest::Client::new());
    // Execute request by using this service.
    let response = client
        .get(format!("{}/hello", mock_server.uri()))
        .send()
        .await?;

    let text = response.body_reader().utf8().await?;
    println!("{text}");

    Ok(())
}

Required Methods§

Source

fn execute<R>( &mut self, request: Request<R>, ) -> impl Future<Output = Result<Response<RespBody>, Err>>
where ReqBody: From<R>,

Executes an HTTP request.

Provided Methods§

Source

fn request<U>( &mut self, method: Method, uri: U, ) -> ClientRequestBuilder<'_, Self, Err, RespBody>
where U: IntoUri, Uri: TryFrom<U::TryInto>, <Uri as TryFrom<U::TryInto>>::Error: Into<Error>,

Starts building a request with the given method and URI.

Source

fn get<U>(&mut self, uri: U) -> ClientRequestBuilder<'_, Self, Err, RespBody>
where U: IntoUri, Uri: TryFrom<U::TryInto>, <Uri as TryFrom<U::TryInto>>::Error: Into<Error>,

Convenience method to make a GET request to a given URL.

Source

fn put<U>(&mut self, uri: U) -> ClientRequestBuilder<'_, Self, Err, RespBody>
where U: IntoUri, Uri: TryFrom<U::TryInto>, <Uri as TryFrom<U::TryInto>>::Error: Into<Error>,

Convenience method to make a PUT request to a given URL.

Source

fn post<U>(&mut self, uri: U) -> ClientRequestBuilder<'_, Self, Err, RespBody>
where U: IntoUri, Uri: TryFrom<U::TryInto>, <Uri as TryFrom<U::TryInto>>::Error: Into<Error>,

Convenience method to make a POST request to a given URL.

Source

fn patch<U>(&mut self, uri: U) -> ClientRequestBuilder<'_, Self, Err, RespBody>
where U: IntoUri, Uri: TryFrom<U::TryInto>, <Uri as TryFrom<U::TryInto>>::Error: Into<Error>,

Convenience method to make a PATCH request to a given URL.

Source

fn delete<U>(&mut self, uri: U) -> ClientRequestBuilder<'_, Self, Err, RespBody>
where U: IntoUri, Uri: TryFrom<U::TryInto>, <Uri as TryFrom<U::TryInto>>::Error: Into<Error>,

Convenience method to make a DELETE request to a given URL.

Source

fn head<U>(&mut self, uri: U) -> ClientRequestBuilder<'_, Self, Err, RespBody>
where U: IntoUri, Uri: TryFrom<U::TryInto>, <Uri as TryFrom<U::TryInto>>::Error: Into<Error>,

Convenience method to make a HEAD request to a given URL.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety".

Implementors§

Source§

impl<S, ReqBody, RespBody, Err> ServiceExt<ReqBody, RespBody, Err> for S
where S: Service<Request<ReqBody>, Response = Response<RespBody>, Error = Err>, S::Future: Send + 'static, S::Error: 'static,