126Implement an HTTP cache with ETag validation, stale-while-revalidate, and request deduplication
Problem
Implement a client-side HTTP cache that follows the server's caching headers: createHttpCache({ fetch, now = Date.now }) returns { get(url) }, which resolves with { status, body, fromCache }.
The server sends ETag and Cache-Control headers, for example Cache-Control: max-age=60, stale-while-revalidate=300.
Rules for get(url):
- No entry: fetch, and store
{ body, etag, storedAt, maxAge, swr }unless the response hasCache-Control: no-store. Only cache200responses. - Fresh (age <
max-ageseconds): return the cached body without a request (fromCache: true). - Stale but within
stale-while-revalidate: return the cached body immediately and revalidate in the background. - Older than that: revalidate and wait for the result.
- Revalidating sends
If-None-Match: <etag>when there is an ETag. A304 Not Modifiedkeeps the cached body and resets its age; a200replaces the entry. - Deduplication: concurrent
gets for the same URL that need the network share one request. - A failed background revalidation keeps the stale entry; a failed blocking request rejects.
fetch(url, { headers }) resolves with a standard Response. Body text can be read with await response.text().
Try it yourself
Write your solution, run it, then submit to check it against the tests.
Press Run or ⌘ Enter to execute your code.
Step-by-step
Split the header on commas, trim, and read max-age=N, stale-while-revalidate=N and no-store. Missing values mean 0 (always stale) and no stale window.
Unlock the full solution
What's inside
- Step-by-step
- Approach
- Solution
- Complexity
- Edge cases
- Follow-up questions
- Tests
Includes 2 code listings, 5 edge cases, 4 follow-up questions.
One-time payment by UPI, card or net banking. Launch price.