feat(api): server-side manifest listing endpoint (read path for #5535) - #5537
Open
petfold wants to merge 3 commits into
Open
feat(api): server-side manifest listing endpoint (read path for #5535)#5537petfold wants to merge 3 commits into
petfold wants to merge 3 commits into
Conversation
Add GET /manifest/{address}/{path}, which walks the Mantaray trie
server-side and returns entries as JSON, so clients no longer need to
fetch and traverse the trie chunk by chunk just to list a collection.
Semantics follow S3 ListObjectsV2: optional path prefix, an optional
delimiter for shallow (pseudo-directory) listings, lexicographic
pagination via limit/after, and opt-in per-entry sizes.
- pkg/manifest: add the optional EntryWalker interface (+ ErrStopWalk)
and implement WalkEntry on the mantaray manifest over the existing
sorted WalkNode, without expanding the core Interface.
- pkg/api: manifestListHandler + route, reusing the /bzz manifest
resolution and ACT decryption chain; per-entry size via the root
chunk span.
- openapi: document the path plus ManifestList/ManifestListEntry schemas.
- tests: recursive, delimiter, prefix, pagination and 404 cases over a
real mantaray fixture, including the empty root-metadata entry.
Refs ethersphere#5535
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
OpenAPI requires every in:path parameter to be required:true; an optional path parameter fails spec validation and broke the OpenAPI Preview CI check. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Raise the manifest listing page cap to 1000000 and document what it bounds (per-request buffered memory, not total enumeration, which stays unbounded via after/nextMarker). An over-cap limit now returns 400 rather than being silently clamped, so the client keeps an accurate view of its page size; a non-positive limit falls back to the default. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
petfold
marked this pull request as ready for review
July 15, 2026 05:30
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.
Summary
Adds a read-only, server-side manifest listing endpoint, implementing the read half of #5535.
Bee currently has no way to enumerate a manifest's contents over HTTP — clients must download and walk the Mantaray trie themselves, chunk by chunk via
/bytes(one round trip per node). This endpoint walks the trie on the node and returns entries as JSON, turning O(trie nodes) round trips into O(pages). Semantics mirror S3ListObjectsV2:delimiter/→ shallow listing: direct entries +commonPrefixes. Unset → recursive.limitafter/nextMarker). Hard cap 1000000; a higher value is rejected with 400 rather than silently clamped, and a non-positive value falls back to the default.aftersizesfalseResponse:
{ entries[], commonPrefixes[], truncated, nextMarker }.This is deliberately listing only. The companion server-side mutation endpoint sketched in #5535 is a separate follow-up.
Implementation
Everything needed already existed in the tree:
pkg/manifest— a small optionalEntryWalkerinterface (+ErrStopWalk), implemented asWalkEntryon the mantaray manifest over the existing sortedWalkNode. This keeps the coremanifest.Interfaceandsimple.gountouched and doesn't expose the trie representation to callers.pkg/api/manifest.go—manifestListHandler, mirroring the/bzzdownload path's manifest resolution (loadsave.NewReadonly→NewDefaultManifestReference) and reusing the ACT decryption chain, so encrypted/ACT manifests resolve unchanged. Pagination uses a last-consumed-path marker that is correct for both recursive and delimiter modes.openapi/— path +ManifestList/ManifestListEntryschemas.No new storage, protocol, or incentive-layer behavior — purely a local read amplification of data the node already serves.
Testing
pkg/api/manifest_test.go): recursive,delimiter=/, prefix, multi-page pagination round-trip, missing-prefix 404, and over-cap-limit 400, over a real mantaray fixture (incl. the empty root-metadata entry).go test ./pkg/api/ ./pkg/manifest/...green;go vetandgofmtclean.POST /bzzuploader. All cases correct, andsizes=truereturned exact byte lengths from real chunk spans. The live run caught one bug the synthetic test missed — theRootPathmetadata entry carries a 32-zero-byte reference (notswarm.ZeroAddress, which has nil bytes), so it leaked as a/entry until the skip was aligned with theIterateAddressesconvention.Known limitations / scope (draft — feedback welcome on the API shape)
Opening as a draft to agree the API before polishing. Deliberately out of scope here, happy to address based on review:
WalkNodehas no pruning hook, sodelimiter=/walks a subtree fully to emit onecommonPrefixesentry — output is correct but not yet the cheap shallow listing it should be. The clean fix is a pruning-aware walk in the mantaray layer.afteris a post-filter), so paginating N pages is ~O(N × subtree) node loads. A trie-seek toafterwould fix it.prefixis directory-boundary-only, not an arbitrary S3 byte-prefix (e.g.prefix=da404s;data/works). Documented as such; could addHasPrefix-style handling.sizes=trueon encrypted refs is silently unsupported. Thelimithard cap bounds buffered response memory but not the number of trie nodes walked to build a page.website-index-document) is currently dropped from the listing; API: server-side manifest listing endpoint (S3-style), with optional manifest mutation as a follow-up #5535 proposes surfacing it as a top-levelmanifestMetadata— easy to add if wanted.Refs #5535.