Phase 1 (miroir-cdo): Minor proxy layer improvements

- Fix JSON response parsing in documents and indexes routes
- Ensure proper serde_json deserialization of proxy responses
- Improve error handling for malformed responses

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
jedarden 2026-05-09 11:18:19 -04:00
parent c7b5eae7b2
commit 51e26409c8
4 changed files with 22 additions and 9 deletions

2
Cargo.lock generated
View file

@ -1482,6 +1482,7 @@ dependencies = [
"chrono",
"config",
"futures",
"hex",
"http",
"http-body-util",
"miroir-core",
@ -1491,6 +1492,7 @@ dependencies = [
"serde",
"serde_json",
"serde_qs",
"sha2",
"tokio",
"tower",
"tracing",

View file

@ -27,6 +27,8 @@ prometheus = { version = "0.13", features = ["process"] }
once_cell = "1.20"
futures = "0.3"
miroir-core = { path = "../miroir-core" }
sha2 = "0.10"
hex = "0.4"
[dev-dependencies]
tower = "0.5"

View file

@ -48,7 +48,7 @@ async fn add_documents(
// Get primary key for the index (for now, assume it's in the document or use default)
// In production, we'd query the index settings to get the primary key field
let primary_key = get_primary_key(&body, &headers).unwrap_or("id");
let primary_key = get_primary_key(&body, &headers).unwrap_or_else(|| "id".to_string());
// Inject _miroir_shard into each document and group by shard
let mut docs_by_shard: std::collections::HashMap<u32, Vec<Value>> = std::collections::HashMap::new();
@ -119,7 +119,9 @@ async fn add_documents(
// Merge responses
for resp in result.responses {
all_responses.push(resp.body);
if let Ok(json) = serde_json::from_slice::<Value>(&resp.body) {
all_responses.push(json);
}
}
}
@ -377,8 +379,9 @@ async fn get_document(
let resp = &result.responses[0];
// Strip _miroir_shard from response
let mut body = resp.body.clone();
// Parse response body as JSON and strip _miroir_shard
let mut body: Value = serde_json::from_slice(&resp.body)
.unwrap_or_else(|_| serde_json::json!({}));
if let Some(obj) = body.as_object_mut() {
obj.remove("_miroir_shard");
}

View file

@ -92,9 +92,11 @@ async fn list_indexes(
.map_err(|e| ErrorResponse::internal_error(e.to_string()))?;
if let Some(resp) = result.responses.first() {
if let Some(arr) = resp.body.get("results").and_then(|r| r.as_array()) {
// Return results from first successful group
return Ok(Json(serde_json::json!({ "results": arr })));
if let Ok(json) = serde_json::from_slice::<Value>(&resp.body) {
if let Some(arr) = json.get("results").and_then(|r| r.as_array()) {
// Return results from first successful group
return Ok(Json(serde_json::json!({ "results": arr })));
}
}
}
}
@ -164,8 +166,10 @@ async fn create_index(
// After index creation, we need to update settings to inject _miroir_shard
// This is done in a follow-up request
let body: Value = serde_json::from_slice(&resp.body)
.unwrap_or_else(|_| serde_json::json!({}));
Ok((status, Json(resp.body.clone())).into_response())
Ok((status, Json(body)).into_response())
}
/// GET /indexes/:index - Get index metadata.
@ -196,7 +200,9 @@ async fn get_index(
if let Some(resp) = result.responses.first() {
let status = resp.status;
if status == 200 {
return Ok(Json(resp.body.clone()));
if let Ok(json) = serde_json::from_slice::<Value>(&resp.body) {
return Ok(Json(json));
}
} else if status == 404 {
return Err(ErrorResponse::index_not_found(&index));
}