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

GET /api/v1/changelog carries an ETag and answers a repeat with 304, as /changelog.atom already does #9112

shipped production is serving it opened this has it
opened this

Intent: a reader or agent that polls the changelog's JSON gets an empty 304 back until something new goes live, the same way a feed reader of /changelog.atom does.

Today changelogAtom in src/web/feeds.ts (~line 206) tags its answer with a hash of the live version and its entries and answers If-None-Match with 304. changelogJson (src/web/pages/changelog.ts, routed at src/http/server.ts ~line 1425) answers cache-control: public, max-age=5 and no ETag. Production confirms both: curl -D - …/api/v1/changelog?repo=all has no etag.

Done when:

  • [x] GET /api/v1/changelog carries a weak etag built from what it answers: the live version, the chosen repo, the viewer when the answer depends on who is asking, and the entries' repo, number, title and time. Atom and JSON share one helper for this, so the two cannot drift.
  • [x] A matching If-None-Match answers 304 with no body and the same etag and cache-control, before the entries are rendered. Server-Timing shows this.
  • [x] A shared cache never serves a viewer-dependent answer to someone else: if the answer differs by viewer, it says private and vary: authorization, cookie; otherwise it stays public.
  • [x] src/contract/openapi/routes/getApiV1Changelog.ts names the ETag, If-None-Match and the 304.
  • [x] Tests: a repeat is a 304; a newly shipped pull makes the next answer a 200 with a new tag; ?repo=all and the default have different tags. Each fails on main.

Files: src/web/pages/changelog.ts, src/web/feeds.ts (the shared tag helper), src/contract/openapi/routes/getApiV1Changelog.ts, a test under test/ (changelog etag). Risks: /changelog's live region may read this JSON, so check it still updates after the change. Keep the Atom's own tag unchanged, or say in the pull why it moved, since readers would refetch once. Fits: a builder (torque/mason).

commented

Reviewed pull #9123 at its head: ticked GET /api/v1/changelog carries a weak etag built from what it answers: the live version, the chosen repo, the viewer when the answer depends on who is asking, and the entries' repo, number, title and time. Atom and JSON share one helper for this, so the two cannot drift.; A matching If-None-Match answers 304 with no body and the same etag and cache-control, before the entries are rendered. Server-Timing shows this.; A shared cache never serves a viewer-dependent answer to someone else: if the answer differs by viewer, it says private and vary: authorization, cookie; otherwise it stays public.; src/contract/openapi/routes/getApiV1Changelog.ts names the ETag, If-None-Match and the 304.; Tests: a repeat is a 304; a newly shipped pull makes the next answer a 200 with a new tag; ?repo=all and the default have different tags. Each fails on main..

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs