メインコンテンツまでスキップ

Redis KVドライバ

@zeltjs/kv@zeltjs/kv/adaptor-redis エントリポイント経由でRedisバックエンドを提供します。RedisKVAdaptorioredis の上に AtomicKVAdaptor を実装し、incrsetnx などのatomic操作をサポートします。

インストール

pnpm add @zeltjs/kv @zeltjs/redis

Peer dependency:

pnpm add @zeltjs/core

基本的なセットアップ

RedisKVAdaptor をinjectして、namespace化されたストアを作成します。namespace()AtomicKVStore を直接返し、get() は値(キーが存在しない場合は undefined)に解決されます — unwrapが必要なresultラッパーはありません:

@Injectable()
export class CacheService {
  private store: AtomicKVStore;

  constructor(kv = inject(RedisKVAdaptor)) {
    this.store = kv.namespace('cache:');
  }

  async get<T>(key: string): Promise<T | undefined> {
    return this.store.get<T>(key);
  }

  async set<T extends Defined>(key: string, value: T, ttlSec?: number): Promise<void> {
    await this.store.set(key, value, { ttlSec });
  }
}

アプリ作成時に RedisConfigRedisKVAdaptor を登録します。RedisConfig が接続設定を提供し(RedisKVAdaptor が依存する RedisService がそれを利用します)、依存関係は自動的に解決されるので、injectablesRedisKVAdaptor を挙げるだけで十分です:

const app = createApp([http({
    controllers: [AppController],
  })], { configs: [RedisConfig] });

デフォルトでは、RedisConfig は接続URLを環境変数 REDIS_URL から読み取り、未設定時は redis://localhost:6379 にフォールバックします。

カスタム設定

RedisConfig を継承して接続設定をカスタマイズします。options getterはioredisの RedisOptions を返します:

@Config
class CustomRedisConfig extends RedisConfig {
  override get url(): string {
    return this.env.getString('REDIS_URL', 'redis://localhost:6379');
  }

  override get options() {
    return {
      maxRetriesPerRequest: 3,
      retryStrategy: (times: number) => Math.min(times * 100, 3000),
    };
  }
}

デフォルトの代わりにカスタムconfigを登録します:

const app = createApp([http({
    controllers: [AppController],
  })], { configs: [CustomRedisConfig] });

APIリファレンス

RedisKVAdaptor

メソッド説明
namespace(prefix)namespace化された AtomicKVStore を返す

RedisKVAdaptor はアプリケーションのライフサイクルに参加します。基盤となるioredis接続は RedisService が保持しており、シャットダウン時に自動的に切断されます(グレースフルシャットダウンを参照)。

AtomicKVStoreのメソッド

メソッド説明
get<T>(key)値を取得する。存在しない場合は undefined
set<T>(key, value, opts?)値をオプションのTTL付きで保存する
del(key)キーを削除する
has(key)キーが存在するか確認する
expire(key, ttlSec)既存のキーのTTLを更新する
incr(key, by?, opts?)atomicなインクリメント
setnx<T>(key, value, opts?)存在しない場合のみsetする
namespace(prefix)ネストしたnamespaceを作成する

本番環境のセットアップ

本番デプロイでは、接続プーリングとリトライ動作を設定します:

@Config
class ProductionRedisConfig extends RedisConfig {
  override get options() {
    return {
      maxRetriesPerRequest: 3,
      enableReadyCheck: true,
      retryStrategy: (times: number) => {
        if (times > 10) return null;
        return Math.min(times * 200, 5000);
      },
    };
  }
}

グレースフルシャットダウン

Redisを手動で切断する必要はありません。RedisService がライフサイクルマネージャに自身を登録するため、アプリケーションのシャットダウン時にioredisクライアントが自動的に切断されます。

@zeltjs/adapter-node を使う場合、onNode がこのシャットダウンをトリガーする SIGINT/SIGTERM ハンドラをインストールし、handle.shutdown() も同じことを行います:

const handle = await nodeApp.http.listen({ port: 3000 });

// サーバーを切断し、ライフサイクルのシャットダウン(Redisを含む)を実行する
await handle.shutdown();