Start learning free

LESSON 123 OF 173 · BACKEND: SPEED

Cache an Answer

Practice

The product list is the shop's busiest page, and it rarely changes, so running the same query for every visitor is wasted work. A cache keeps an answer you already worked out, so you can give it again without the work.

The simplest cache is an object: its property names say what is remembered, their values are the remembered answers. An empty {} has no properties TypeScript knows of, so you give it a type that says what it may hold. Look for the property first; if it's there, give the remembered answer; if not, do the work and store the result. Here is the idea on another value, squares of numbers:

const squares: { [n: number]: number } = {};

function square(n: number): number {
  if (squares[n] !== undefined) {
    return squares[n];
  }
  const result = n * n;
  squares[n] = result;
  return result;
}

The first call fills the cache, every later call reads it. Count the queries to prove it: two lists, one query. Only GET /products uses the cache, so GET /products/1 still asks the database. Your code must give these answers, in this order:

GET /products  →  200  [{"category": "kitchen", "id": 1, "name": "Mug", "price": 12, "stock": 10}, … 8 products]
GET /debug/queries  →  200  {"queries": 1}
GET /products  →  200  [the same 8 products]
GET /debug/queries  →  200  {"queries": 1}
GET /products/1  →  200  {"category": "kitchen", "id": 1, "name": "Mug", "price": 12, "stock": 10}
GET /debug/queries  →  200  {"queries": 2}

The cache lives in the app's memory, not in the database, so it starts empty each time the app starts.

Your task: below stats, add an empty object cache with the type { products?: Product[] }: the ? says products may be missing. In the route for GET /products, store rows in cache under the name products just before res.json(rows), and, as the first lines, answer the remembered list right away when cache.products is not undefined.


Assignment
Follow the Coding Tutorial to cache the product list, so only the first GET /products runs the query.


Hint
The check must come before the query, or the query has already run. Put return in front of res.json inside the check, so the route's function stops there.


STEP 1 OF 4
    Ctrl + Enter to check