Trait generic_api_client::http::RequestHandler
source · pub trait RequestHandler<B> {
type Successful;
type Unsuccessful;
type BuildError;
fn build_request(
&self,
builder: RequestBuilder,
request_body: &Option<B>,
attempt_count: u8
) -> Result<Request, Self::BuildError>;
fn handle_response(
&self,
status: StatusCode,
headers: HeaderMap,
response_body: Bytes
) -> Result<Self::Successful, Self::Unsuccessful>;
fn request_config(&self) -> RequestConfig { ... }
}
Expand description
A trait
which is used to process requests and responses for the Client.
Required Associated Types§
sourcetype Successful
type Successful
The type which is returned to the caller of Client::request() when the response was successful.
sourcetype Unsuccessful
type Unsuccessful
The type which is returned to the caller of Client::request() when the response was unsuccessful.
sourcetype BuildError
type BuildError
The type that represents an error occurred in build_request().
Required Methods§
sourcefn build_request(
&self,
builder: RequestBuilder,
request_body: &Option<B>,
attempt_count: u8
) -> Result<Request, Self::BuildError>
fn build_request(
&self,
builder: RequestBuilder,
request_body: &Option<B>,
attempt_count: u8
) -> Result<Request, Self::BuildError>
Build a HTTP request to be sent.
Implementors have to decide how to include the request_body
into the builder
. Implementors can
also perform other operations (such as authorization) on the request.
sourcefn handle_response(
&self,
status: StatusCode,
headers: HeaderMap,
response_body: Bytes
) -> Result<Self::Successful, Self::Unsuccessful>
fn handle_response(
&self,
status: StatusCode,
headers: HeaderMap,
response_body: Bytes
) -> Result<Self::Successful, Self::Unsuccessful>
Handle a HTTP response before it is returned to the caller of Client::request().
You can verify, parse, etc… the response here before it is returned to the caller.
Examples
fn handle_response(&self, status: StatusCode, _: HeaderMap, response_body: Bytes) -> Result<String, ()> {
if status.is_success() {
let body = std::str::from_utf8(&response_body).expect("body should be valid UTF-8").to_owned();
Ok(body)
} else {
Err(())
}
}
Provided Methods§
sourcefn request_config(&self) -> RequestConfig
fn request_config(&self) -> RequestConfig
Returns a RequestConfig that will be used to send a HTTP reqeust.
Examples found in repository?
src/http.rs (line 37)
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
pub async fn request<Q, B, H>(
&self, method: Method, url: &str, query: Option<&Q>, body: Option<B>, handler: &H,
) -> Result<H::Successful, RequestError<H::BuildError, H::Unsuccessful>>
where
Q: Serialize + ?Sized,
H: RequestHandler<B>,
{
let config = handler.request_config();
config.verify();
let url = config.url_prefix + url;
let mut count = 1;
loop {
// create RequestBuilder
let mut request_builder = self.client.request(method.clone(), url.clone())
.timeout(config.timeout);
if let Some(query) = query {
request_builder = request_builder.query(query);
}
let request = handler.build_request(request_builder, &body, count)
.map_err(|error| {
RequestError::BuildRequestError(error)
})?;
// send the request
match self.client.execute(request).await {
Ok(mut response) => {
let status = response.status();
let headers = std::mem::take(response.headers_mut());
let body = response.bytes().await.map_err(|error| {
RequestError::ReceiveResponse(error)
})?;
return handler.handle_response(status, headers, body).map_err(|error| {
RequestError::ResponseHandleError(error)
});
},
Err(error) => {
if count >= config.max_try {
// max retry count
return Err(RequestError::SendRequest(error));
}
log::warn!("Retrying sending reqeust");
// else, continue
count += 1;
tokio::time::sleep(config.retry_cooldown).await;
},
}
}
}