Start learning free

LESSON 167 OF 173 · BACKEND: BACKEND WITH AI

The AI's Cache Never Forgets

Practice

To make GET /products fast, the shop keeps the product list in an object called cache, of type { products?: Product[] }: it may hold a list of products, or nothing yet. The first request reads the database and remembers the list; every later one answers from memory. An AI assistant wrote the route that changes a price:

app.patch("/products/:productId", (req: Request, res: Response) => {
  const productId = Number(req.params.productId);
  const data = req.body;
  const result = db.prepare("UPDATE products SET price = ? WHERE id = ?").run(data.price, productId);
  if (result.changes === 0) {
    return res.status(404).json({ error: "Product not found" });
  }
  res.json({ id: productId, price: data.price });
});

The new price is saved, but nobody tells the cache. After PATCH /products/1 sets the Mug to 14, GET /products keeps answering the list it remembered, with the Mug at 12, until the app restarts. The remembered list is stale: true once, wrong now.

The rule for any cache: every route that changes the data clears what was remembered about it. If the shop also cached its categories (one more optional property in the cache's type, categories?: string[]), the route that adds one would forget that list:

app.post("/categories", (req: Request, res: Response) => {
  const data = req.body;
  db.prepare("INSERT INTO categories (name) VALUES (?)").run(data.name);
  delete cache.categories;   // forget the remembered list
  res.status(201).json({ name: data.name });
});

The delete operator takes one property out of an object. TypeScript allows it on an optional property, one marked with ? in the type. If the property isn't there, nothing happens. The requests and the answers your app must give:

GET /products  →  200  [{"id": 1, "name": "Mug", "price": 12}, {"id": 2, "name": "Notebook", "price": 7}, …]   (8 products)
PATCH /products/1  {"price": 14}  →  200  {"id": 1, "price": 14}
GET /products  →  200  [{"id": 1, "name": "Mug", "price": 14}, {"id": 2, "name": "Notebook", "price": 7}, …]
PATCH /products/99  {"price": 5}  →  404  {"error": "Product not found"}
PATCH /products/4  {"price": 3}  →  200  {"id": 4, "price": 3}
GET /products  →  200  [{"id": 1, "name": "Mug", "price": 14}, …, {"id": 4, "name": "Pen", "price": 3}, …]

Your task: rewrite the route for PATCH /products/:productId. Its first line, which reads the id from the path into productId as a number, is ready. Save the new price, answer 404 when no product has that id, clear the cache after a real change, and answer the id and the new price.


Assignment
Follow the Coding Tutorial to rewrite the PATCH /products/:productId route so the shop shows every new price at once.


Hint
The line the AI forgot is delete cache.products;. Put it after the 404 check: when no product changed, the remembered list is still true, so there is nothing to forget.


STEP 1 OF 6
    Ctrl + Enter to check