javascript 35 lines · 8 steps

Conditional GET caching in Express

An Express route serves an article but returns 304 Not Modified when the client's cached copy is still fresh.

Explained by highlit
1const express = require('express');
2const router = express.Router();
3 
4router.get('/articles/:slug', async (req, res, next) => {
5 try {
6 const article = await Article.findOne({ slug: req.params.slug });
7 
8 if (!article) {
9 return res.status(404).json({ error: 'Article not found' });
10 }
11 
12 const lastModified = article.updatedAt;
13 res.set('Last-Modified', lastModified.toUTCString());
14 res.set('Cache-Control', 'public, max-age=0, must-revalidate');
15 
16 const ifModifiedSince = req.get('If-Modified-Since');
17 if (ifModifiedSince) {
18 const since = new Date(ifModifiedSince);
19 if (!Number.isNaN(since.getTime()) && lastModified.getTime() <= since.getTime() + 999) {
20 return res.status(304).end();
21 }
22 }
23 
24 res.json({
25 slug: article.slug,
26 title: article.title,
27 body: article.body,
28 updatedAt: lastModified.toISOString(),
29 });
30 } catch (err) {
31 next(err);
32 }
33});
34 
35module.exports = router;
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Sending Last-Modified lets clients revalidate cheaply instead of refetching unchanged data.
  2. 2A 304 response has no body, so you save bandwidth when nothing has changed.
  3. 3Comparing timestamps needs a small tolerance because HTTP dates have second-level precision.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Conditional GET caching in Express — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code