app: Refactor API calls

This commit is contained in:
Valentin Tolmer 2021-05-25 10:03:33 +02:00
parent e07efc9585
commit 9899c6f5aa

View File

@ -22,30 +22,41 @@ fn get_claims_from_jwt(jwt: &str) -> Result<JWTClaims> {
Ok(token.claims().clone()) Ok(token.claims().clone())
} }
fn create_handler<Resp, CallbackResult, F>(
callback: Callback<Result<CallbackResult>>,
handler: F,
) -> Callback<Response<Result<Resp>>>
where
F: Fn(http::StatusCode, Resp) -> Result<CallbackResult> + 'static,
Resp: std::fmt::Display,
CallbackResult: 'static,
{
Callback::once(move |response: Response<Result<Resp>>| {
let (meta, maybe_data) = response.into_parts();
let message = maybe_data
.map_err(|e| anyhow!("Could not reach server: {}", e))
.and_then(|data| handler(meta.status, data));
callback.emit(message)
})
}
impl HostService { impl HostService {
pub fn list_users( pub fn list_users(
request: ListUsersRequest, request: ListUsersRequest,
callback: Callback<Result<Vec<User>>>, callback: Callback<Result<Vec<User>>>,
) -> Result<FetchTask> { ) -> Result<FetchTask> {
let url = "/api/users"; let url = "/api/users";
let handler = move |response: Response<Result<String>>| {
let (meta, maybe_data) = response.into_parts();
let message = maybe_data
.map_err(|e| anyhow!("Could not fetch: {}", e))
.and_then(|data| {
if meta.status.is_success() {
serde_json::from_str(&data)
.map_err(|e| anyhow!("Could not parse response: {}", e))
} else {
Err(anyhow!("[{}]: {}", meta.status, data))
}
});
callback.emit(message)
};
let request = Request::post(url) let request = Request::post(url)
.header("Content-Type", "application/json") .header("Content-Type", "application/json")
.body(Json(&request))?; .body(Json(&request))?;
FetchService::fetch_with_options(request, get_default_options(), handler.into()) let handler = create_handler(callback, |status, data: String| {
if status.is_success() {
serde_json::from_str(&data).map_err(|e| anyhow!("Could not parse response: {}", e))
} else {
Err(anyhow!("[{}]: {}", status, data))
}
});
FetchService::fetch_with_options(request, get_default_options(), handler)
} }
pub fn authenticate( pub fn authenticate(
@ -53,12 +64,11 @@ impl HostService {
callback: Callback<Result<String>>, callback: Callback<Result<String>>,
) -> Result<FetchTask> { ) -> Result<FetchTask> {
let url = "/auth"; let url = "/auth";
let handler = move |response: Response<Result<String>>| { let request = Request::post(url)
let (meta, maybe_data) = response.into_parts(); .header("Content-Type", "application/json")
let message = maybe_data .body(Json(&request))?;
.map_err(|e| anyhow!("Could not reach authentication server: {}", e)) let handler = create_handler(callback, |status, data: String| {
.and_then(|data| { if status.is_success() {
if meta.status.is_success() {
get_claims_from_jwt(&data) get_claims_from_jwt(&data)
.map_err(|e| anyhow!("Could not parse response: {}", e)) .map_err(|e| anyhow!("Could not parse response: {}", e))
.and_then(|jwt_claims| { .and_then(|jwt_claims| {
@ -66,40 +76,25 @@ impl HostService {
.map(|_| jwt_claims.user.clone()) .map(|_| jwt_claims.user.clone())
.map_err(|e| anyhow!("Error clearing cookie: {}", e)) .map_err(|e| anyhow!("Error clearing cookie: {}", e))
}) })
} else if meta.status == 401 { } else if status == 401 {
Err(anyhow!("Invalid username or password")) Err(anyhow!("Invalid username or password"))
} else { } else {
Err(anyhow!( Err(anyhow!("Could not authenticate: [{}]: {}", status, data))
"Could not authenticate: [{}]: {}",
meta.status,
data
))
} }
}); });
callback.emit(message) FetchService::fetch_with_options(request, get_default_options(), handler)
};
let request = Request::post(url)
.header("Content-Type", "application/json")
.body(Json(&request))?;
FetchService::fetch_with_options(request, get_default_options(), handler.into())
} }
pub fn logout(callback: Callback<Result<()>>) -> Result<FetchTask> { pub fn logout(callback: Callback<Result<()>>) -> Result<FetchTask> {
let url = "/auth/logout"; let url = "/auth/logout";
let handler = move |response: Response<Result<String>>| { let request = Request::post(url).body(yew::format::Nothing)?;
let (meta, maybe_data) = response.into_parts(); let handler = create_handler(callback, |status, data: String| {
let message = maybe_data if status.is_success() {
.map_err(|e| anyhow!("Could not reach authentication server: {}", e))
.and_then(|data| {
if meta.status.is_success() {
Ok(()) Ok(())
} else { } else {
Err(anyhow!("Could not logout: [{}]: {}", meta.status, data)) Err(anyhow!("Could not logout: [{}]: {}", status, data))
} }
}); });
callback.emit(message) FetchService::fetch_with_options(request, get_default_options(), handler)
};
let request = Request::post(url).body(yew::format::Nothing)?;
FetchService::fetch_with_options(request, get_default_options(), handler.into())
} }
} }