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§

The type which is returned to the caller of Client::request() when the response was successful.

The type which is returned to the caller of Client::request() when the response was unsuccessful.

The type that represents an error occurred in build_request().

Required Methods§

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.

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§

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;
                },
            }
        }
    }

Implementors§