Skip to content

Commit 0c2e384

Browse files
authored
chore(volo-http): use less Result in client (#509)
This commit updates `Request` to `Result<Request>` in `RequestBuilder`, and makes the methods of `RequestBuilder` no longer use `Result` as the return type. These methods no longer return `Err` directly, but save it in `Result<Request>` and throw it when trying to send a request. Signed-off-by: Yu Li <[email protected]>
1 parent c7e4fc8 commit 0c2e384

File tree

7 files changed

+305
-142
lines changed

7 files changed

+305
-142
lines changed

examples/src/http/example-http-client.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ async fn main() -> Result<(), BoxError> {
5555
client
5656
.request_builder()
5757
.host("httpbin.org")
58-
.uri("/get")?
58+
.uri("/get")
5959
.send()
6060
.await?
6161
.into_string()
@@ -65,7 +65,7 @@ async fn main() -> Result<(), BoxError> {
6565
println!(
6666
"{}",
6767
client
68-
.get("http://127.0.0.1:8080/")?
68+
.get("http://127.0.0.1:8080/")
6969
.send()
7070
.await?
7171
.into_string()
@@ -77,7 +77,7 @@ async fn main() -> Result<(), BoxError> {
7777
"{:?}",
7878
client
7979
.request_builder()
80-
.uri("/user/json_get")?
80+
.uri("/user/json_get")
8181
.send()
8282
.await?
8383
.into_json::<Person>()
@@ -86,12 +86,12 @@ async fn main() -> Result<(), BoxError> {
8686
println!(
8787
"{:?}",
8888
client
89-
.post("/user/json_post")?
89+
.post("/user/json_post")
9090
.json(&Person {
9191
name: "Foo".to_string(),
9292
age: 25,
9393
phones: vec!["114514".to_string()],
94-
})?
94+
})
9595
.send()
9696
.await?
9797
.into_string()
@@ -103,7 +103,7 @@ async fn main() -> Result<(), BoxError> {
103103
println!(
104104
"{}",
105105
client
106-
.get("http://127.0.0.1:8080/")?
106+
.get("http://127.0.0.1:8080/")
107107
.send()
108108
.await?
109109
.into_string()
@@ -114,7 +114,7 @@ async fn main() -> Result<(), BoxError> {
114114
println!(
115115
"{:?}",
116116
client
117-
.get("/")?
117+
.get("/")
118118
.send()
119119
.await
120120
.expect_err("this request should fail"),

volo-http/src/client/mod.rs

+34-30
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use self::{
4040
use crate::{
4141
context::{client::Config, ClientContext},
4242
error::{
43-
client::{builder_error, no_address, ClientError},
43+
client::{builder_error, no_address, ClientError, Result},
4444
BoxError,
4545
},
4646
request::ClientRequest,
@@ -463,7 +463,7 @@ impl<IL, OL, C, LB> ClientBuilder<IL, OL, C, LB> {
463463
}
464464

465465
/// Insert a header to the request.
466-
pub fn header<K, V>(&mut self, key: K, value: V) -> Result<&mut Self, ClientError>
466+
pub fn header<K, V>(&mut self, key: K, value: V) -> Result<&mut Self>
467467
where
468468
K: TryInto<HeaderName>,
469469
K::Error: Error + Send + Sync + 'static,
@@ -681,6 +681,7 @@ impl<IL, OL, C, LB> ClientBuilder<IL, OL, C, LB> {
681681
};
682682

683683
let client_inner = ClientInner {
684+
service,
684685
caller_name,
685686
callee_name: self.callee_name,
686687
default_target: self.target,
@@ -690,14 +691,14 @@ impl<IL, OL, C, LB> ClientBuilder<IL, OL, C, LB> {
690691
headers: self.headers,
691692
};
692693
let client = Client {
693-
service,
694694
inner: Arc::new(client_inner),
695695
};
696696
self.mk_client.mk_client(client)
697697
}
698698
}
699699

700-
struct ClientInner {
700+
struct ClientInner<S> {
701+
service: S,
701702
caller_name: FastStr,
702703
callee_name: FastStr,
703704
default_target: Target,
@@ -718,7 +719,6 @@ struct ClientInner {
718719
/// let client = Client::builder().build();
719720
/// let resp = client
720721
/// .get("http://httpbin.org/get")
721-
/// .expect("invalid uri")
722722
/// .send()
723723
/// .await
724724
/// .expect("failed to send request")
@@ -728,17 +728,23 @@ struct ClientInner {
728728
/// println!("{resp:?}");
729729
/// # })
730730
/// ```
731-
#[derive(Clone)]
732731
pub struct Client<S> {
733-
service: S,
734-
inner: Arc<ClientInner>,
732+
inner: Arc<ClientInner<S>>,
733+
}
734+
735+
impl<S> Clone for Client<S> {
736+
fn clone(&self) -> Self {
737+
Self {
738+
inner: Arc::clone(&self.inner),
739+
}
740+
}
735741
}
736742

737743
macro_rules! method_requests {
738744
($method:ident) => {
739745
paste! {
740746
#[doc = concat!("Create a request with `", stringify!([<$method:upper>]) ,"` method and the given `uri`.")]
741-
pub fn [<$method:lower>]<U>(&self, uri: U) -> Result<RequestBuilder<S>, ClientError>
747+
pub fn [<$method:lower>]<U>(&self, uri: U) -> RequestBuilder<S>
742748
where
743749
U: TryInto<Uri>,
744750
U::Error: Into<BoxError>,
@@ -759,16 +765,16 @@ impl Client<()> {
759765
impl<S> Client<S> {
760766
/// Create a builder for building a request.
761767
pub fn request_builder(&self) -> RequestBuilder<S> {
762-
RequestBuilder::new(self)
768+
RequestBuilder::new(self.clone())
763769
}
764770

765771
/// Create a builder for building a request with the specified method and URI.
766-
pub fn request<U>(&self, method: Method, uri: U) -> Result<RequestBuilder<S>, ClientError>
772+
pub fn request<U>(&self, method: Method, uri: U) -> RequestBuilder<S>
767773
where
768774
U: TryInto<Uri>,
769775
U::Error: Into<BoxError>,
770776
{
771-
RequestBuilder::new(self).method(method).uri(uri)
777+
RequestBuilder::new(self.clone()).method(method).uri(uri)
772778
}
773779

774780
method_requests!(options);
@@ -907,7 +913,7 @@ where
907913

908914
let has_metainfo = METAINFO.try_with(|_| {}).is_ok();
909915

910-
let fut = self.service.call(cx, req);
916+
let fut = self.inner.service.call(cx, req);
911917

912918
if has_metainfo {
913919
fut.await
@@ -929,12 +935,12 @@ impl<S> MkClient<Client<S>> for DefaultMkClient {
929935
}
930936

931937
/// Create a GET request to the specified URI.
932-
pub async fn get<U>(uri: U) -> Result<ClientResponse, ClientError>
938+
pub async fn get<U>(uri: U) -> Result<ClientResponse>
933939
where
934940
U: TryInto<Uri>,
935941
U::Error: Into<BoxError>,
936942
{
937-
ClientBuilder::new().build().get(uri)?.send().await
943+
ClientBuilder::new().build().get(uri).send().await
938944
}
939945

940946
// The `httpbin.org` always responses a json data.
@@ -945,7 +951,10 @@ mod client_tests {
945951
use std::{collections::HashMap, future::Future};
946952

947953
use http::{header, StatusCode};
948-
use motore::{layer::Layer, service::Service};
954+
use motore::{
955+
layer::{Layer, Stack},
956+
service::Service,
957+
};
949958
use serde::Deserialize;
950959
use volo::{context::Endpoint, layer::Identity};
951960

@@ -974,7 +983,7 @@ mod client_tests {
974983
const USER_AGENT_KEY: &str = "User-Agent";
975984
const USER_AGENT_VAL: &str = "volo-http-unit-test";
976985

977-
#[allow(unused)]
986+
#[test]
978987
fn client_types_check() {
979988
struct TestLayer;
980989
struct TestService<S> {
@@ -1016,6 +1025,10 @@ mod client_tests {
10161025
.layer_inner(TestLayer)
10171026
.layer_outer(TestLayer)
10181027
.build();
1028+
let _: DefaultClient<Stack<TestLayer, TestLayer>> = ClientBuilder::new()
1029+
.layer_inner(TestLayer)
1030+
.layer_inner(TestLayer)
1031+
.build();
10191032
}
10201033

10211034
#[tokio::test]
@@ -1038,7 +1051,6 @@ mod client_tests {
10381051

10391052
let resp = client
10401053
.get(HTTPBIN_GET)
1041-
.unwrap()
10421054
.send()
10431055
.await
10441056
.unwrap()
@@ -1058,7 +1070,6 @@ mod client_tests {
10581070

10591071
let resp = client
10601072
.get("/get")
1061-
.unwrap()
10621073
.send()
10631074
.await
10641075
.unwrap()
@@ -1081,7 +1092,6 @@ mod client_tests {
10811092

10821093
let resp = client
10831094
.get("/get")
1084-
.unwrap()
10851095
.send()
10861096
.await
10871097
.unwrap()
@@ -1101,7 +1111,6 @@ mod client_tests {
11011111

11021112
let resp = client
11031113
.get("/get")
1104-
.unwrap()
11051114
.send()
11061115
.await
11071116
.unwrap()
@@ -1128,7 +1137,6 @@ mod client_tests {
11281137

11291138
let resp = client
11301139
.get("/get")
1131-
.unwrap()
11321140
.send()
11331141
.await
11341142
.unwrap()
@@ -1145,7 +1153,7 @@ mod client_tests {
11451153
builder.host("httpbin.org").with_port(443);
11461154
let client = builder.build();
11471155

1148-
let resp = client.get("/get").unwrap().send().await.unwrap();
1156+
let resp = client.get("/get").send().await.unwrap();
11491157
// Send HTTP request to the HTTPS port (443), `httpbin.org` will response `400 Bad
11501158
// Request`.
11511159
assert_eq!(resp.status(), StatusCode::BAD_REQUEST);
@@ -1161,7 +1169,6 @@ mod client_tests {
11611169
"{}",
11621170
client
11631171
.get("/post")
1164-
.unwrap()
11651172
.send()
11661173
.await
11671174
.expect_err("GET for httpbin.org/post should fail")
@@ -1183,7 +1190,6 @@ mod client_tests {
11831190
"{}",
11841191
client
11851192
.get("https://httpbin.org/get")
1186-
.unwrap()
11871193
.send()
11881194
.await
11891195
.expect_err("HTTPS with disable_tls should fail")
@@ -1222,7 +1228,7 @@ mod client_tests {
12221228
builder.target_parser(callopt_should_not_inserted);
12231229
let client = builder.build();
12241230

1225-
let resp = client.get(HTTPBIN_GET).unwrap().send().await;
1231+
let resp = client.get(HTTPBIN_GET).send().await;
12261232
assert!(resp.is_ok());
12271233
}
12281234

@@ -1233,7 +1239,7 @@ mod client_tests {
12331239
builder.target_parser(callopt_should_not_inserted);
12341240
let client = builder.build();
12351241

1236-
let resp = client.get(HTTPBIN_GET).unwrap().send().await;
1242+
let resp = client.get(HTTPBIN_GET).send().await;
12371243
assert!(resp.is_ok());
12381244
}
12391245

@@ -1245,7 +1251,6 @@ mod client_tests {
12451251

12461252
let resp = client
12471253
.get(HTTPBIN_GET)
1248-
.unwrap()
12491254
.with_callopt(CallOpt::new().with(CallOptInserted))
12501255
.send()
12511256
.await;
@@ -1261,7 +1266,6 @@ mod client_tests {
12611266

12621267
let resp = client
12631268
.get(HTTPBIN_GET)
1264-
.unwrap()
12651269
// insert an empty callopt
12661270
.with_callopt(CallOpt::new())
12671271
.send()
@@ -1277,7 +1281,7 @@ mod client_tests {
12771281
builder.target_parser(callopt_should_not_inserted);
12781282
let client = builder.build();
12791283

1280-
let resp = client.get(HTTPBIN_GET).unwrap().send().await;
1284+
let resp = client.get(HTTPBIN_GET).send().await;
12811285
assert!(resp.is_ok());
12821286
}
12831287
}

0 commit comments

Comments
 (0)