pub struct ClientRequestBuilder<'a, S, Err, RespBody> { /* private fields */ }
Expand description
An http::Request
builder.
Generally, this builder copies the behavior of the http::request::Builder
,
but unlike it, this builder contains a reference to the client and is able to send a
constructed request. Also, this builder borrows most useful methods from the reqwest
one.
Implementations§
Source§impl<'a, S, Err, RespBody> ClientRequestBuilder<'a, S, Err, RespBody>
impl<'a, S, Err, RespBody> ClientRequestBuilder<'a, S, Err, RespBody>
Sourcepub fn method<T>(self, method: T) -> Self
pub fn method<T>(self, method: T) -> Self
Sets the HTTP method for this request.
By default this is GET
.
Sourcepub fn uri<U: IntoUri>(self, uri: U) -> Self
pub fn uri<U: IntoUri>(self, uri: U) -> Self
Sets the URI for this request
By default this is /
.
Sourcepub fn version(self, version: Version) -> Self
pub fn version(self, version: Version) -> Self
Set the HTTP version for this request.
By default this is HTTP/1.1.
Sourcepub fn header<K, V>(self, key: K, value: V) -> Selfwhere
HeaderName: TryFrom<K>,
HeaderValue: TryFrom<V>,
<HeaderName as TryFrom<K>>::Error: Into<Error>,
<HeaderValue as TryFrom<V>>::Error: Into<Error>,
pub fn header<K, V>(self, key: K, value: V) -> Selfwhere
HeaderName: TryFrom<K>,
HeaderValue: TryFrom<V>,
<HeaderName as TryFrom<K>>::Error: Into<Error>,
<HeaderValue as TryFrom<V>>::Error: Into<Error>,
Appends a header to this request.
This function will append the provided key/value as a header to the
internal HeaderMap
being constructed. Essentially this is
equivalent to calling HeaderMap::append
.
Sourcepub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>>
pub fn headers_mut(&mut self) -> Option<&mut HeaderMap<HeaderValue>>
Returns a mutable reference to headers of this request builder.
If builder contains error returns None
.
Sourcepub fn extensions_mut(&mut self) -> Option<&mut Extensions>
pub fn extensions_mut(&mut self) -> Option<&mut Extensions>
Returns a mutable reference to the extensions of this request builder.
If builder contains error returns None
.
Sourcepub fn body<NewReqBody>(
self,
body: impl Into<NewReqBody>,
) -> Result<ClientRequest<'a, S, Err, NewReqBody, RespBody>, Error>
pub fn body<NewReqBody>( self, body: impl Into<NewReqBody>, ) -> Result<ClientRequest<'a, S, Err, NewReqBody, RespBody>, Error>
“Consumes” this builder, using the provided body
to return a
constructed ClientRequest
.
§Errors
Same as the http::request::Builder::body
Sourcepub fn json<T: Serialize + ?Sized>(
self,
value: &T,
) -> Result<ClientRequest<'a, S, Err, Bytes, RespBody>, SetBodyError<Error>>
Available on crate feature json
only.
pub fn json<T: Serialize + ?Sized>( self, value: &T, ) -> Result<ClientRequest<'a, S, Err, Bytes, RespBody>, SetBodyError<Error>>
json
only.Sets a JSON body for this request.
Additionally this method adds a CONTENT_TYPE
header for JSON body.
If you decide to override the request body, keep this in mind.
§Errors
If the given value’s implementation of serde::Serialize
decides to fail.
§Examples
use bytes::Bytes;
use serde::{Deserialize, Serialize};
use tower::{ServiceBuilder, ServiceExt as _};
use tower_http::ServiceBuilderExt as _;
use tower_http_client::{ResponseExt as _, ServiceExt as _};
use tower_reqwest::{into_reqwest_body, HttpClientLayer};
use wiremock::{
matchers::{method, path},
Mock, MockServer, ResponseTemplate,
};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
struct SomeInfo {
name: String,
age: u32,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (_mock_server, mock_server_uri) = create_mock_server().await;
eprintln!("-> Creating an HTTP client with Tower layers...");
let mut client = ServiceBuilder::new()
// Set the request body type.
.map_request_body(|body: http_body_util::Full<Bytes>| into_reqwest_body(body))
.layer(HttpClientLayer)
.service(reqwest::Client::new())
.map_err(anyhow::Error::msg)
.boxed_clone();
let response = client
.post(format!("{mock_server_uri}/test"))
.json(&SomeInfo {
name: "John".to_string(),
age: 30,
})?
.send()
.await?;
// Check that the request was successful.
assert_eq!(response.status(), 200);
assert_eq!(
response.body_reader().json::<String>().await?,
"I am John and 30 years old"
);
Ok(())
}
async fn create_mock_server() -> (MockServer, String) {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/test"))
.respond_with(move |request: &wiremock::Request| {
let info: SomeInfo = serde_json::from_slice(request.body.as_ref()).unwrap();
eprintln!("Received request with info {info:?}",);
ResponseTemplate::new(200)
.set_body_json(format!("I am {} and {} years old", info.name, info.age))
})
.mount(&mock_server)
.await;
let mock_server_uri = mock_server.uri();
(mock_server, mock_server_uri)
}
Sourcepub fn form<T: Serialize + ?Sized>(
self,
form: &T,
) -> Result<ClientRequest<'a, S, Err, String, RespBody>, SetBodyError<Error>>
Available on crate feature form
only.
pub fn form<T: Serialize + ?Sized>( self, form: &T, ) -> Result<ClientRequest<'a, S, Err, String, RespBody>, SetBodyError<Error>>
form
only.Sets a form body for this request.
Additionally this method adds a CONTENT_TYPE
header for form body.
If you decide to override the request body, keep this in mind.
§Errors
If the given value’s implementation of serde::Serialize
decides to fail.
§Examples
use bytes::Bytes;
use serde::{Deserialize, Serialize};
use tower::{ServiceBuilder, ServiceExt as _};
use tower_http::ServiceBuilderExt as _;
use tower_http_client::{ResponseExt as _, ServiceExt as _};
use tower_reqwest::{into_reqwest_body, HttpClientLayer};
use wiremock::{
matchers::{method, path},
Mock, MockServer, ResponseTemplate,
};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
struct SomeInfo {
name: String,
age: u32,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let (_mock_server, mock_server_uri) = create_mock_server().await;
eprintln!("-> Creating an HTTP client with Tower layers...");
let mut client = ServiceBuilder::new()
// Set the request body type.
.map_request_body(|body: http_body_util::Full<Bytes>| into_reqwest_body(body))
.layer(HttpClientLayer)
.service(reqwest::Client::new())
.map_err(anyhow::Error::msg)
.boxed_clone();
let response = client
.post(format!("{mock_server_uri}/test"))
.form(&SomeInfo {
name: "John".to_string(),
age: 30,
})?
.send()
.await?;
// Check that the request was successful.
assert_eq!(response.status(), 200);
assert_eq!(
response.body_reader().json::<String>().await?,
"I am John and 30 years old"
);
Ok(())
}
async fn create_mock_server() -> (MockServer, String) {
let mock_server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/test"))
.respond_with(move |request: &wiremock::Request| {
let info: SomeInfo = serde_urlencoded::from_bytes(request.body.as_ref()).unwrap();
eprintln!("Received request with info {info:?}",);
ResponseTemplate::new(200)
.set_body_json(format!("I am {} and {} years old", info.name, info.age))
})
.mount(&mock_server)
.await;
let mock_server_uri = mock_server.uri();
(mock_server, mock_server_uri)
}
Sourcepub fn typed_header<T>(self, header: T) -> Selfwhere
T: Header,
Available on crate feature typed_header
only.
pub fn typed_header<T>(self, header: T) -> Selfwhere
T: Header,
typed_header
only.Appends a typed header to this request.
This function will append the provided header as a header to the
internal HeaderMap
being constructed. Essentially this is
equivalent to calling headers::HeaderMapExt::typed_insert
.
Sourcepub fn build(self) -> ClientRequest<'a, S, Err, (), RespBody>
pub fn build(self) -> ClientRequest<'a, S, Err, (), RespBody>
Consumes this builder and returns a constructed request without a body.
§Errors
If erroneous data was passed during the query building process.