feat: add generic search client traits and adapters#994
Open
Conversation
Introduce a family of search client traits with blanket implementations and adapter utilities to reduce boilerplate across backends. New traits ---------- - ItemsClient: single-page item search (search required); defaults: item, items - StreamItemsClient: streaming items across pages (search_stream required); defaults: collect_items, item_count, items_stream - CollectionsClient: fetch all collections (collections required); default: collection point-lookup - PagedCollectionsClient: cursor-paginated collections (collections_page required) for future backends that support paginated /collections - StreamCollectionsClient: streaming collections (collections_stream required); default: collect_collections - ArrowItemsClient (geoarrow feature): Arrow record batch output (search_to_arrow required); default: items_to_arrow - TransactionClient: write operations Blanket implementations ----------------------- - CollectionsClient + Clone + Sync -> StreamCollectionsClient (eager fetch) - ArrowItemsClient + Sync -> ItemsClient + StreamItemsClient (geoarrow feature) Adapter utilities ----------------- - PagedItemsStream<T>: wraps ItemsClient to provide StreamItemsClient via token/skip pagination using ItemCollection::next - stream_pages_generic: free function driving the pagination loop - stream_pages_collections_generic: collections equivalent for PagedCollectionsClient backends - RecordBatchReaderAdapter<I> (geoarrow feature): bridges any Iterator<Item = Result<RecordBatch, E>> to arrow_array::RecordBatchReader Documentation ------------- Add docs/search-clients.md covering the trait family, blanket impls, adapter conversion chart, pagination mechanics, and performance notes.
gadomski
requested changes
Mar 18, 2026
- gate async stream traits/exports behind the core async feature - rename pagination helpers to stream_pages and stream_pages_collections - move search client guidance into api module docs and remove duplicate docs page - unify arrow adapter errors under crate::Error and stream record batches incrementally - replace mock-heavy adapter tests with real MemoryBackend streaming tests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Introduce a family of search client traits with blanket implementations and adapter utilities, replacing ad-hoc per-backend boilerplate with a consistent, extensible design.
New traits (
stac::api)ItemsClientsearchStreamItemsClientsearch_streamCollectionsClientcollectionsPagedCollectionsClientcollections_pageStreamCollectionsClientcollections_streamArrowItemsClient(geoarrow)search_to_arrowTransactionClientadd_item,add_collectionBlanket implementations
CollectionsClient + Clone + Sync → StreamCollectionsClient— eagerly fetches all collections and yields as a stream; no wrapper struct neededArrowItemsClient + Sync → ItemsClient + StreamItemsClient(geoarrow feature) — collects record batches synchronously and returns owned itemsAdapter utilities
PagedItemsStream\<T>— wraps anyItemsClientto provideStreamItemsClientvia token/skip pagination (ItemCollection::next)stream_pages_generic— free function driving the items pagination loop; used byPagedItemsStreamand all server backendsstream_pages_collections_generic— collections equivalent forPagedCollectionsClientbackends (ready for future paginated/collectionssupport)RecordBatchReaderAdapter\<I>(geoarrow) — bridgesIterator<Item = Result<RecordBatch, E>>toarrow_array::RecordBatchReaderBackend implementations
All three server backends (memory, duckdb, pgstac) implement the full trait family.
stac-duckdbprovidesHrefClient(ArrowItemsClient) andSyncHrefClient(ItemsClient+CollectionsClient+StreamItemsClientviaMutex).stac-io'sClientimplementsStreamItemsClientwith HATEOAS link-following rather than token pagination.Design notes
ItemsClient + Clone → StreamItemsClientblanket cannot be added because it would overlap with theArrowItemsClientblanket under Rust's coherence rules. Server backends usestream_pages_genericdirectly in their explicitStreamItemsClientimpls.PagedCollectionsClienthas no blanketStreamCollectionsClientfor the same reason (would overlap with theCollectionsClientblanket). Paginated backends callstream_pages_collections_genericin their own impl.Related issues
Checklist
prek run --all-files)