feat(indexer): add ETag caching for GET /streams and GET /splits responses - #713
Open
olatechy0 wants to merge 5 commits into
Open
feat(indexer): add ETag caching for GET /streams and GET /splits responses#713olatechy0 wants to merge 5 commits into
olatechy0 wants to merge 5 commits into
Conversation
Return an ETag on GET /streams and GET /splits responses derived from a hash of the response body joined with the data's last-updated timestamp, and answer 304 Not Modified (no body) when the client sends a matching If-None-Match header. - server.ts: add computeEtag/jsonWithEtag helpers and wire the If-None-Match header into both handlers. Adds the missing /splits indexer endpoint serving the account's current splits config. - db.ts: add getDripsStreamsLastUpdated, getDripsSplitsLastUpdated, and queryDripsSplits (aggregates receivers from current_streams with a stable hash). - test: cover first request (200 + ETag), unchanged (304 with matching If-None-Match), and changed data (new ETag) for both endpoints. Closes vestflow-labs#674
|
@olatechy0 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Contributor
|
RESOLVE CONFLIUCTS |
Resolve conflicts with upstream main (multi-line signature reformatting of numParam, handleStreams, getDripsStreamingTvl, queryGivesForAccount; newer indexer work): - db.ts: keep the PR's getDripsStreamsLastUpdated / getDripsSplitsLastUpdated / queryDripsSplits additions while adopting main's formatting for the shared functions they landed adjacent to. No duplicate exports (main has none of these symbols). - server.ts: retain computeEtag/jsonWithEtag from the PR; keep main's single-line numParam formatting; merge main's multi-line handleStreams signature with the PR's new optional ifNoneMatch parameter. Verified: 'npx tsc --noEmit' in indexer/ passes; 'npm run test:drips-api' passes (ETag/304 scenarios). The drips-events type-check failure (TS2783 in the untouched test helper) is identical on main/HEAD and pre-existing.
Author
|
@libby-coder @Ceejaytech25 - The branch conflicts are resolved and the branch is up to date with main. I merged the latest main into feat/etag-caching and resolved the conflicts in indexer/src/db.ts and indexer/src/server.ts, keeping the ETag/304 additions intact alongside main's surrounding reformatting. Verification:
The PR is now conflict-free and mergeable - ready for review. CI is just waiting on approval to run for this fork PR. Thanks! |
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
Closes #674 — Return an
ETagheader onGET /streamsandGET /splitsresponses based on the last-updated timestamp of the data, and respond with 304 Not Modified when the client sends a matchingIf-None-Matchheader.Changes
indexer/src/server.tscomputeEtag— a strong ETag derived from a SHA-256 hash of the canonical JSON body joined with the data's last-updated timestamp. It is stable across identical payloads and changes the instant the underlying data changes.jsonWithEtag— writes theETagheader on every 200 response and answers 304 Not Modified (no body) whenIf-None-Matchmatches the current ETag.If-None-MatchintohandleStreams.GET /splitsindexer endpoint (the SDK already calls{indexerUrl}/splitsbut the route did not exist), serving the account's current splits config with the same ETag/304 behavior.indexer/src/db.tsgetDripsStreamsLastUpdated(account)— most recentcreated_at/ended_atacross an account's streams, for the/streamsETag.getDripsSplitsLastUpdated(account)— most recentupdated_atacross an account'scurrent_streamsrows, for the/splitsETag.queryDripsSplits(account)— aggregates the account's splits receivers fromcurrent_streams(verbatimstream_setreceivers) with a stable SHA-256hashand alast_updatedvalue.Behavior
GET /streams?account=…&network=…→200withETag;304(no body) whenIf-None-Matchmatches; a newETagas soon as stream data changes.GET /splits?account=…&network=…→200withETag;304whenIf-None-Matchmatches; a newETagwhen the account's splits config changes.Tests (
indexer/test/drips-api.test.ts)Added focused regression tests for both endpoints covering the acceptance criteria:
200with anETagheader.If-None-Matchreturns304with no body.ETag(stream added; splits config updated), and the new ETag then validates to304.Verification
npx ts-node --transpile-only test/drips-api.test.ts→ passes (covers the ETag scenarios).npx ts-node --transpile-only test/drips-events-projection.test.ts→ passes.npx tsc --noEmitinindexer/shows only two pre-existing errors in thegiveshandler (GiveQueryParams/queryGivesnot defined at HEAD);db.tshas no errors. The roottsconfig.jsonexcludesindexer, so CI'sbackend-buildtype-check does not cover the indexer.vitest runsuite has pre-existing failures at HEAD (tough-cookie/jsdom module resolution, andgives-endpointtests that depend on the undefinedqueryGives) — identical failure set onmain; this change adds no new failures.