encore-cache について
Encore の型付き Redis キャッシュラッパーを紹介します。Encore サービスでデータをキャッシュする開発者向けに、クラスターとキースペースで値の型、キー形式、有効期限を定義します。
主な機能
- 01キャッシュクラスターとキースペースの宣言
- 02複数の値型を持つキースペース
- 03キー形式と有効期限の設定
- 04条件付き書き込みとアトミックカウンター
- 05キャッシュミスとキー競合への対応
活用シーン
- 01ユーザーやリソースパスごとのデータキャッシュ
- 02カウンターの増減
- 03キャッシュ値への有効期限設定
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ encoredev/ skills --skill encore-cacheインストール後、Claude Code で/encore-cacheを入力して読み込まれたか確認します。
詳細
Encore キャッシュ (Redis)
手順
Encore のキャッシュは、Redis の型付きラッパーです。CacheCluster を一度宣言し、必要なデータの形状ごとに Keyspace オブジェクトを作成します。
クラスター
import { CacheCluster } from "encore.dev/storage/cache";
const cluster = new CacheCluster("my-cache", {
evictionPolicy: "allkeys-lru",
});
別のサービスからクラスターを参照する: const cluster = CacheCluster.named("my-cache");
削除ポリシー: "allkeys-lru" (デフォルト)、"noeviction"、"allkeys-lfu"、"allkeys-random"、"volatile-lru"、"volatile-lfu"、"volatile-ttl"、"volatile-random"。
キースペースの型
各キースペースには、キーの形状 (keyPattern から Redis キーを構築するために使用されます) と値の型があります。
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: "[email protected]" });
// 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");
複数フィールドのキーパターン
interface Key { userId: string; resourcePath: string; }
const requests = new IntKeyspace<Key>(cluster, {
keyPattern: "requests/:userId/:resourcePath",
defaultExpiry: expireIn(10 * 1000),
});
有効期限ヘルパー
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";
書き込みオプション
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
エラー
import { CacheMiss, CacheKeyExists } from "encore.dev/storage/cache";
const value = await keyspace.get(key); // undefined on miss (does not throw)
ガイドライン
CacheClusterとキースペースはパッケージレベルで宣言してください。- 最も具体的なキースペースの型を選んでください — カウンターには
IntKeyspaceを使うと、アトミックなincrement/decrementが無料で手に入ります。 get()はミス時にundefinedを返します。replace()とsetIfNotExists()は競合時に例外をスローします。- ローカル開発では約 100 キー上限のインメモリ Redis を使用します — 負荷テストには使用しないでください。
- 永続ストレージには、代わりに
encore-database(Postgres) またはencore-bucket(オブジェクトストレージ) を使用してください。
コメント
Markdown 対応