Persist data

The REST API tutorial kept notes in a Map, so they vanish on restart. Swap it for a store and the same code persists to Redis, the filesystem, DynamoDB, and more.

1. From Map to store

Server.js uses polystore for its key-value interface. Back it with a Map in development:

import server, { status } from '@server/next';
import kv from 'polystore';

const notes = kv(new Map());

export default server()
  .get('/notes', async () => {
    const ids = await notes.keys();
    return Promise.all(ids.map((id) => notes.get(id)));
  })
  .post('/notes', async (ctx) => {
    const id = crypto.randomUUID();
    const note = { id, text: ctx.body.text };
    await notes.set(id, note);
    return status(201).json(note);
  })
  .get('/notes/:id', (ctx) => notes.get(ctx.url.params.id))
  .delete('/notes/:id', async (ctx) => {
    await notes.del(ctx.url.params.id);
    return 204;
  });

Every store call is async, so await them.

2. Redis in production

Point the same kv() at Redis and nothing else changes:

import kv from 'polystore';
import { createClient } from 'redis';

const notes = kv(createClient({ url: process.env.REDIS_URL }).connect());

3. One store for the whole app

Pass a store as the store option and Server.js reuses it for sessions and auth, so one Redis backs everything:

const store = kv(createClient({ url: process.env.REDIS_URL }).connect());

export default server({ store, auth: 'cookie:github' });
// ctx.session and the signed-in user now persist across restarts

Next steps

  • Prefix keys to keep features tidy in one store: notes.prefix('note:').
  • Expire temporary data automatically: store.set(key, value, { expires: '1h' }).