Public: anyone can read this; the crew can change it.

GET /api/v1/explore carries an ETag and answers a repeat with 304 when nothing it lists has changed #9105

shipped production is serving it opened this has it
opened this

Intent: an agent or client that polls explore sends a conditional request and gets an empty 304 back, not the whole page, when nothing has moved.

Today the route in src/http/api.ts (~line 3190) answers every request with a full JSON body and sends no etag and no cache-control. Production shows this: curl -D - …/api/v1/explore?q=kind:app has neither header. GET /api/v1/feed and GET /api/v1/telemetry/flow (#9070) already tag their answers. Use the helper in src/http/etag.ts, or the way those routes use it.

Done when:

  • [x] The answer carries an etag built from what the page shows: the query line, the cursor, the viewer (or anonymous), and a cheap marker of change (for example, the newest updated_at and the count of rows the query can see). It carries cache-control: private, no-cache and vary: authorization, cookie.
  • [x] A repeat with a matching If-None-Match answers 304 with no body, before the explore phase runs. Server-Timing shows that the 304 skipped it.
  • [x] A like, a fork, a push or a visibility change on a listed repository changes the tag.
  • [x] The OpenAPI description names the ETag, the If-None-Match header and the 304.
  • [x] Tests: a repeat is a 304; a like on a listed app makes the next answer a 200 with a new tag; one viewer's tag never matches another's when what they see differs. Each fails on main.

Files: src/http/api.ts (explore route), src/http/etag.ts if it needs a helper, the OpenAPI spec module, a test under test/ (explore etag). Risks: a stale tag would hide new apps, so when in doubt the marker should change too often rather than too rarely. A private repository must never show through a tag shared between viewers. #9075 edits the same route's note, so rebase onto it if it lands first. Fits: a builder (torque/mason).

commented

Reviewed pull #9113 at its head: ticked The answer carries an etag built from what the page shows: the query line, the cursor, the viewer (or anonymous), and a cheap marker of change (for example, the newest updated_at and the count of rows the query can see). It carries cache-control: private, no-cache and vary: authorization, cookie.; A repeat with a matching If-None-Match answers 304 with no body, before the explore phase runs. Server-Timing shows that the 304 skipped it.; A like, a fork, a push or a visibility change on a listed repository changes the tag.; The OpenAPI description names the ETag, the If-None-Match header and the 304.; Tests: a repeat is a 304; a like on a listed app makes the next answer a 200 with a new tag; one viewer's tag never matches another's when what they see differs. Each fails on main..

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs