From 289b84b09a791b88f039664d71bb644c94de6000 Mon Sep 17 00:00:00 2001 From: tv Date: Fri, 30 Oct 2026 19:13:40 +0100 Subject: api: add support for shallow store reads --- src/api/store.rs | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/api') diff --git a/src/api/store.rs b/src/api/store.rs index d0fc807..7e8caed 100644 --- a/src/api/store.rs +++ b/src/api/store.rs @@ -32,6 +32,10 @@ pub(crate) struct ReadQuery { /// to base a replacing remake on exactly what was read. #[serde(default)] heads: bool, + /// What's there, one level deep (`store::read_shallow`), to browse a large store a + /// level at a time. + #[serde(default)] + shallow: bool, } #[derive(Debug, Deserialize)] @@ -54,6 +58,9 @@ pub(crate) async fn get_store_root( headers: HeaderMap, Query(query): Query, ) -> Result { + if query.shallow { + return shallow(&state, Vec::new(), true, &query).await; + } let accept = headers.get(ACCEPT).cloned(); let want_conflicts = query.conflicts; @@ -91,6 +98,9 @@ pub(crate) async fn get_store_entry( Query(query): Query, ) -> Result { let path = parse_key_path(&key)?; + if query.shallow { + return shallow(&state, path, false, &query).await; + } let accept = headers.get(ACCEPT).cloned(); let want_conflicts = query.conflicts; @@ -121,6 +131,33 @@ pub(crate) async fn get_store_entry( mark_source(response, source, heads) } +/// `?shallow=true`: what's at `path`, one level deep, as JSON (`store::read_shallow`); +/// with conflicts asked for too, `400`. `unready_live` as `render_read` has it. +async fn shallow( + state: &AppState, + path: Vec, + unready_live: bool, + query: &ReadQuery, +) -> Result { + if query.conflicts { + return Err(StatusCode::BAD_REQUEST); + } + let (response, source, heads) = state + .render_read( + unready_live, + query.heads, + move |doc| store::read_shallow(doc, &path), + move |result| { + let value = result + .map_err(|e| store_status(e, "Failed to read store path"))? + .ok_or(StatusCode::NOT_FOUND)?; + response_for_value(&value, None) + }, + ) + .await?; + mark_source(response, source, heads) +} + /// Header on reads served from the pre-rejoin document; its value is that epoch. const STALE_HEADER: &str = "x-continuum-stale"; -- cgit v1.3.1