Cache Encore (Redis)
Instructions
Le cache d'Encore est un wrapper typé autour de Redis. Déclarez une CacheCluster une fois, puis créez des objets Keyspace pour chaque forme de données dont vous avez besoin.
Cluster
import { CacheCluster } from "encore.dev/storage/cache";
const cluster = new CacheCluster("my-cache", {
evictionPolicy: "allkeys-lru",
});
Référencez un cluster depuis un autre service : const cluster = CacheCluster.named("my-cache");
Politiques d'éviction : "allkeys-lru" (par défaut), "noeviction", "allkeys-lfu", "allkeys-random", "volatile-lru", "volatile-lfu", "volatile-ttl", "volatile-random".
Types de keyspace
Chaque keyspace a une forme de clé (utilisée pour construire la clé Redis à partir de keyPattern) et un type de valeur.
import {
StringKeyspace,
IntKeyspace,
FloatKeyspace,
StructKeyspace,
StringListKeyspace,
NumberListKeyspace,
StringSetKeyspace,
NumberSetKeyspace,
expireIn,
} from "encore.dev/storage/cache";
// Strings
const tokens = new StringKeyspace<{ tokenId: string }>(cluster, {
keyPattern: "token/:tokenId",
defaultExpiry: expireIn(3600 * 1000),
});
await tokens.set({ tokenId: "abc" }, "value");
const val = await tokens.get({ tokenId: "abc" }); // undefined on miss
// Integers (atomic counters)
const counters = new IntKeyspace<{ userId: string }>(cluster, {
keyPattern: "requests/:userId",
defaultExpiry: expireIn(10 * 1000),
});
const count = await counters.increment({ userId: "user123" }, 1);
// Structs (JSON)
interface UserProfile { name: string; email: string; }
const profiles = new StructKeyspace<{ userId: string }, UserProfile>(cluster, {
keyPattern: "profile/:userId",
defaultExpiry: expireIn(3600 * 1000),
});
await profiles.set({ userId: "123" }, { name: "Alice", email: "alice@example.com" });
// Lists
const recent = new StringListKeyspace<{ userId: string }>(cluster, {
keyPattern: "recent/:userId",
});
await recent.pushRight({ userId: "user123" }, "item1", "item2");
// Sets
const tags = new StringSetKeyspace<{ articleId: string }>(cluster, {
keyPattern: "tags/:articleId",
});
await tags.add({ articleId: "post1" }, "typescript", "encore");
const has = await tags.contains({ articleId: "post1" }, "typescript");
Motifs de clé multi-champs
interface Key { userId: string; resourcePath: string; }
const requests = new IntKeyspace<Key>(cluster, {
keyPattern: "requests/:userId/:resourcePath",
defaultExpiry: expireIn(10 * 1000),
});
Assistants d'expiration
import {
expireIn, // milliseconds
expireInSeconds,
expireInMinutes,
expireInHours,
expireDailyAt, // a specific UTC time each day
neverExpire,
keepTTL, // keep existing TTL when updating
} from "encore.dev/storage/cache";
Options d'écriture
await keyspace.set(key, value, { expiry: expireInMinutes(30) });
await keyspace.set(key, value, { expiry: keepTTL });
await keyspace.setIfNotExists(key, value); // throws CacheKeyExists if present
await keyspace.replace(key, value); // throws CacheMiss if absent
Erreurs
import { CacheMiss, CacheKeyExists } from "encore.dev/storage/cache";
const value = await keyspace.get(key); // undefined on miss (does not throw)
Recommandations
- Déclarez
CacheClusteret les keyspaces au niveau du package. - Choisissez le type de keyspace le plus spécifique —
IntKeyspacepour les compteurs vous offre gratuitement les opérations atomiquesincrement/decrement. get()retourneundefineden cas d'absence ;replace()etsetIfNotExists()lèvent une exception en cas de conflit.- Le développement local utilise une Redis en mémoire avec une limite d'environ 100 clés — ne la testez pas en charge.
- Pour le stockage durable, utilisez
encore-database(Postgres) ouencore-bucket(stockage objet) à la place.