Skip to content

Commit ce0133c

Browse files
committed
Update make_request function to use ApiEncoding for input encoding
1 parent ee252ea commit ce0133c

File tree

1 file changed

+72
-85
lines changed

1 file changed

+72
-85
lines changed

frontend/common/src/utils/client/make_request.rs

Lines changed: 72 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,15 @@ use http::Method;
1010
use leptos::{
1111
server_fn::{
1212
client::browser::BrowserClient,
13-
codec::{Encoding, FromReq, IntoReq, Json},
13+
codec::{Encoding, FromReq, GetUrl, IntoReq, PostUrl},
1414
middleware::Layer,
1515
request::{browser::BrowserRequest, ClientReq},
1616
ServerFn,
1717
},
1818
ServerFnError,
1919
};
2020
use matchit::Router;
21-
use models::{
22-
prelude::*,
23-
utils::{GenericResponse, IntoAxumResponse},
24-
};
21+
use models::{prelude::*, utils::GenericResponse};
2522
use preprocess::Preprocessable;
2623
use serde::{Serialize, de::DeserializeOwned};
2724

@@ -47,15 +44,19 @@ where
4744
E: ApiEndpoint,
4845
{
4946
const CONTENT_TYPE: &'static str =
50-
if <E::ResponseBody as IntoAxumResponse>::is::<GenericResponse>() {
47+
if std::any::TypeId::of::<E::ResponseBody>() == std::any::TypeId::of::<GenericResponse>() {
5148
// If the response body is a GenericResponse, then we can't know the
5249
// content type of the response. So we just return the default content
5350
// type of binary data.
5451
"application/octet-stream"
5552
} else {
56-
Json::CONTENT_TYPE
53+
GetUrl::CONTENT_TYPE
5754
};
58-
const METHOD: Method = E::METHOD;
55+
const METHOD: Method = if Method::GET == E::METHOD {
56+
Method::GET
57+
} else {
58+
Method::POST
59+
};
5960
}
6061

6162
/// A struct that holds the request to be made to the backend. This is used
@@ -81,7 +82,7 @@ where
8182
type Error = ErrorType;
8283
type InputEncoding = ApiEncoding<E>;
8384
type Output = AppResponse<E>;
84-
type OutputEncoding = Json;
85+
type OutputEncoding = ApiEncoding<E>;
8586
#[cfg(not(target_arch = "wasm32"))]
8687
type ServerRequest = http::Request<axum::body::Body>;
8788
#[cfg(target_arch = "wasm32")]
@@ -94,7 +95,51 @@ where
9495
const PATH: &'static str = <E::RequestPath as TypedPath>::PATH;
9596

9697
async fn run_body(self) -> Result<Self::Output, ServerFnError<Self::Error>> {
97-
todo!()
98+
use std::net::{IpAddr, SocketAddr};
99+
100+
use axum::extract::ConnectInfo;
101+
use axum_extra::routing::TypedPath;
102+
use tower::{
103+
ServiceBuilder,
104+
ServiceExt,
105+
service_fn,
106+
util::{BoxCloneService, BoxLayer},
107+
};
108+
109+
let ConnectInfo(socket_addr) = leptos_axum::extract::<ConnectInfo<SocketAddr>>()
110+
.await
111+
.map_err(ErrorType::server_error)?;
112+
let layer = API_CALL_REGISTRY
113+
.get()
114+
.expect("API call registry not initialized")
115+
.read()
116+
.expect("API call registry poisoned")
117+
.get(&E::METHOD)
118+
.unwrap_or_else(|| panic!("API call registry does not contain {}", E::METHOD))
119+
.at(<E::RequestPath as TypedPath>::PATH)
120+
.unwrap_or_else(|_| {
121+
panic!(
122+
"could not find route at path `{}`",
123+
<E::RequestPath as TypedPath>::PATH
124+
)
125+
})
126+
.value
127+
.downcast_ref::<BoxLayer<
128+
BoxCloneService<(ApiRequest<E>, IpAddr), AppResponse<E>, ErrorType>,
129+
(ApiRequest<E>, IpAddr),
130+
AppResponse<E>,
131+
ErrorType,
132+
>>()
133+
.expect("unable to downcast layer")
134+
.to_owned();
135+
ServiceBuilder::new()
136+
.layer(layer)
137+
.service(BoxCloneService::new(service_fn(|_| async move {
138+
unreachable!()
139+
})))
140+
.oneshot((self.request, socket_addr.ip()))
141+
.await
142+
.map_err(ServerFnError::WrappedServerError)
98143
}
99144

100145
fn middlewares() -> Vec<Arc<dyn Layer<Self::ServerRequest, Self::ServerResponse>>> {
@@ -115,9 +160,21 @@ where
115160
accepts: &str,
116161
) -> Result<BrowserRequest, ServerFnError<ErrorType>> {
117162
if E::METHOD == Method::GET {
118-
BrowserRequest::try_new_get(path, Json::CONTENT_TYPE, accepts, query)
163+
BrowserRequest::try_new_get(
164+
path,
165+
GetUrl::CONTENT_TYPE,
166+
accepts,
167+
serde_urlencoded::to_string(self.request.query)
168+
.unwrap()
169+
.as_str(),
170+
)
119171
} else {
120-
BrowserRequest::try_new_post(path, Json::CONTENT_TYPE, accepts, body)
172+
BrowserRequest::try_new_post(
173+
path,
174+
PostUrl::CONTENT_TYPE,
175+
accepts,
176+
serde_json::to_string(&self.request.body).unwrap(),
177+
)
121178
}
122179
}
123180
}
@@ -131,7 +188,7 @@ where
131188
E::ResponseBody: Serialize + DeserializeOwned,
132189
{
133190
async fn from_req(
134-
req: http::Request<axum::body::Body>,
191+
_req: http::Request<axum::body::Body>,
135192
) -> Result<Self, ServerFnError<ErrorType>> {
136193
todo!()
137194
}
@@ -168,80 +225,10 @@ where
168225
{
169226
#[cfg(not(target_arch = "wasm32"))]
170227
{
171-
use std::net::{IpAddr, SocketAddr};
172-
173-
use axum::extract::ConnectInfo;
174-
use axum_extra::routing::TypedPath;
175-
use tower::{
176-
ServiceBuilder,
177-
ServiceExt,
178-
service_fn,
179-
util::{BoxCloneService, BoxLayer},
180-
};
181-
182-
let ConnectInfo(socket_addr) = leptos_axum::extract::<ConnectInfo<SocketAddr>>()
183-
.await
184-
.map_err(ErrorType::server_error)?;
185-
let layer = API_CALL_REGISTRY
186-
.get()
187-
.expect("API call registry not initialized")
188-
.read()
189-
.expect("API call registry poisoned")
190-
.get(&E::METHOD)
191-
.unwrap_or_else(|| panic!("API call registry does not contain {}", E::METHOD))
192-
.at(<E::RequestPath as TypedPath>::PATH)
193-
.unwrap_or_else(|_| {
194-
panic!(
195-
"could not find route at path `{}`",
196-
<E::RequestPath as TypedPath>::PATH
197-
)
198-
})
199-
.value
200-
.downcast_ref::<BoxLayer<
201-
BoxCloneService<(ApiRequest<E>, IpAddr), AppResponse<E>, ErrorType>,
202-
(ApiRequest<E>, IpAddr),
203-
AppResponse<E>,
204-
ErrorType,
205-
>>()
206-
.expect("unable to downcast layer")
207-
.to_owned();
208-
ServiceBuilder::new()
209-
.layer(layer)
210-
.service(BoxCloneService::new(service_fn(|_| async move {
211-
unreachable!()
212-
})))
213-
.oneshot((request, socket_addr.ip()))
214-
.await
215-
.map_err(ServerFnError::WrappedServerError)
228+
MakeRequest { request }.run_body().await
216229
}
217230
#[cfg(target_arch = "wasm32")]
218231
{
219-
use models::utils::Headers;
220-
221-
let response = REQWEST_CLIENT
222-
.get_or_init(reqwest::Client::new)
223-
.request(E::METHOD, format!("/api/{}", request.path.to_string()))
224-
.headers(request.headers.to_header_map())
225-
.query(&request.query)
226-
.json(&request.body)
227-
.send()
228-
.await
229-
.map_err(|err| ServerFnError::Request(err.to_string()))?;
230-
231-
let status_code = response.status();
232-
let headers = E::ResponseHeaders::from_header_map(response.headers())
233-
.map_err(|err| ServerFnError::Response(err.to_string()))?;
234-
let text = response
235-
.text()
236-
.await
237-
.map_err(|err| ServerFnError::Response(err.to_string()))?;
238-
let body =
239-
serde_json::from_str(&text).map_err(|err| ServerFnError::Response(err.to_string()))?;
240-
241-
Ok(AppResponse {
242-
status_code,
243-
headers,
244-
body,
245-
})
232+
MakeRequest { request }.run_on_client().await
246233
}
247234
}

0 commit comments

Comments
 (0)