From ea1a4a4a31ee1ff60955b40a7a664b48fcb3c51a Mon Sep 17 00:00:00 2001 From: Shautvast Date: Fri, 3 Apr 2026 18:07:11 +0200 Subject: [PATCH] less json overhead --- backend/src/routes/routing.rs | 7 ++----- backend/src/routes/search.rs | 9 ++------- backend/src/services/osrm.rs | 17 +++++++++++------ backend/src/services/photon.rs | 28 ++++++++++++---------------- 4 files changed, 27 insertions(+), 34 deletions(-) diff --git a/backend/src/routes/routing.rs b/backend/src/routes/routing.rs index 0248e6b..fa3113d 100644 --- a/backend/src/routes/routing.rs +++ b/backend/src/routes/routing.rs @@ -83,7 +83,7 @@ pub async fn route( } // Call OSRM - let json = osrm + let (body, osrm_code) = osrm .route( &profile, &coordinates, @@ -95,7 +95,7 @@ pub async fn route( .await?; // Check OSRM response code - if let Some(code) = json.get("code").and_then(|c| c.as_str()) { + if let Some(code) = osrm_code.as_deref() { match map_osrm_code(code) { OsrmCodeMapping::Ok => {} // Success, continue OsrmCodeMapping::NoRoute => { @@ -119,9 +119,6 @@ pub async fn route( } } - let body = serde_json::to_string(&json) - .map_err(|e| AppError::InternalError(format!("JSON serialization failed: {e}")))?; - // Cache for 30 minutes cache.set_json(&cache_key, &body, 1800).await; diff --git a/backend/src/routes/search.rs b/backend/src/routes/search.rs index c398f85..d1428ed 100644 --- a/backend/src/routes/search.rs +++ b/backend/src/routes/search.rs @@ -88,13 +88,10 @@ pub async fn search( } // Call Photon - let json = photon + let body = photon .search(&q_clean, query.lat, query.lon, limit, lang, query.bbox.as_deref()) .await?; - let body = serde_json::to_string(&json) - .map_err(|e| AppError::InternalError(format!("JSON serialization failed: {e}")))?; - // Cache the result cache.set_json(&cache_key, &body, 3600).await; @@ -165,9 +162,7 @@ pub async fn reverse( .body(cached)); } - let json = photon.reverse(lat, lon, limit, lang).await?; - let body = serde_json::to_string(&json) - .map_err(|e| AppError::InternalError(format!("JSON serialization failed: {e}")))?; + let body = photon.reverse(lat, lon, limit, lang).await?; cache.set_json(&cache_key, &body, 3600).await; diff --git a/backend/src/services/osrm.rs b/backend/src/services/osrm.rs index a10e8cb..5d94015 100644 --- a/backend/src/services/osrm.rs +++ b/backend/src/services/osrm.rs @@ -32,7 +32,7 @@ impl OsrmService { } /// Request a route from the appropriate OSRM instance. - /// Returns raw JSON from OSRM. + /// Returns the raw JSON body and the OSRM `code` field for error mapping. pub async fn route( &self, profile: &str, @@ -41,7 +41,7 @@ impl OsrmService { steps: bool, geometries: &str, overview: &str, - ) -> Result { + ) -> Result<(String, Option), AppError> { let base = self.base_url_for_profile(profile).ok_or_else(|| { AppError::InvalidParameter(format!("Invalid profile: {profile}")) })?; @@ -64,12 +64,17 @@ impl OsrmService { ))); } - let json: serde_json::Value = resp.json().await.map_err(|e| { - tracing::error!(error = %e, "Failed to parse OSRM response"); - AppError::UpstreamError("Failed to parse routing response".into()) + let body = resp.text().await.map_err(|e| { + tracing::error!(error = %e, "Failed to read OSRM response"); + AppError::UpstreamError("Failed to read routing response".into()) })?; - Ok(json) + // Extract only the `code` field to avoid a full parse. + #[derive(serde::Deserialize)] + struct OsrmCode { code: Option } + let code = serde_json::from_str::(&body).ok().and_then(|r| r.code); + + Ok((body, code)) } /// Health probe for a specific OSRM profile. diff --git a/backend/src/services/photon.rs b/backend/src/services/photon.rs index 69038d4..cd4300f 100644 --- a/backend/src/services/photon.rs +++ b/backend/src/services/photon.rs @@ -18,7 +18,7 @@ impl PhotonService { } } - /// Forward geocoding search. Returns raw JSON from Photon. + /// Forward geocoding search. Returns the raw JSON body from Photon. pub async fn search( &self, q: &str, @@ -27,7 +27,7 @@ impl PhotonService { limit: u32, lang: &str, bbox: Option<&str>, - ) -> Result { + ) -> Result { let mut url = format!("{}/api?q={}&limit={}&lang={}", self.base_url, urlencod(q), limit, lang); if let (Some(lat), Some(lon)) = (lat, lon) { @@ -50,22 +50,20 @@ impl PhotonService { ))); } - let json: serde_json::Value = resp.json().await.map_err(|e| { - tracing::error!(error = %e, "Failed to parse Photon response"); - AppError::UpstreamError("Failed to parse search response".into()) - })?; - - Ok(json) + resp.text().await.map_err(|e| { + tracing::error!(error = %e, "Failed to read Photon response"); + AppError::UpstreamError("Failed to read search response".into()) + }) } - /// Reverse geocoding. Returns raw JSON from Photon. + /// Reverse geocoding. Returns the raw JSON body from Photon. pub async fn reverse( &self, lat: f64, lon: f64, limit: u32, lang: &str, - ) -> Result { + ) -> Result { let url = format!( "{}/reverse?lat={lat}&lon={lon}&limit={limit}&lang={lang}", self.base_url @@ -83,12 +81,10 @@ impl PhotonService { ))); } - let json: serde_json::Value = resp.json().await.map_err(|e| { - tracing::error!(error = %e, "Failed to parse Photon reverse response"); - AppError::UpstreamError("Failed to parse reverse geocoding response".into()) - })?; - - Ok(json) + resp.text().await.map_err(|e| { + tracing::error!(error = %e, "Failed to read Photon reverse response"); + AppError::UpstreamError("Failed to read reverse geocoding response".into()) + }) } /// Health probe.