Skip to content

Adapters Redis

@tsed/adapters-redis provides Redis-backed adapter implementations for Ts.ED adapter workflows.

Installation

sh
npm install --save @tsed/adapters-redis @tsed/redis redis
sh
yarn add @tsed/adapters-redis @tsed/redis redis
sh
pnpm add @tsed/adapters-redis @tsed/redis redis
sh
bun add @tsed/adapters-redis @tsed/redis redis

Exports

  • RedisAdapter
  • OIDCRedisAdapter
  • RedisAdaptersSettings (global TsED.AdaptersOptions extension)

Adapter Options

Common options used with Adapters.invokeAdapter(...):

  • connectionName: Redis connection name (default: default)
  • useHash: store payload using hash strategy (used for OIDC consumable models)
  • keyPrefix: prefix applied to all keys generated by the adapter (entity keys, index keys, OIDC keys)
typescript
const adapter = adapters.invokeAdapter({
  adapter: RedisAdapter,
  collectionName: "client",
  model: Client,
  keyPrefix: "tests:e2e:run-42"
});

Redis Module Configuration

@tsed/adapters-redis uses connections provided by @tsed/redis.

Single Connection

typescript
import {Configuration} from "@tsed/di";
import "@tsed/redis";

@Configuration({
  redis: [
    {
      name: "default",
      url: "redis://localhost:6379"
      // or socket: {host: "localhost", port: 6379}
    }
  ]
})
export class Server {}

Cluster

typescript
import {Configuration} from "@tsed/di";
import "@tsed/redis";

@Configuration({
  redis: [
    {
      name: "default",
      nodes: [{url: "redis://localhost:7000"}, {url: "redis://localhost:7001"}, {url: "redis://localhost:7002"}]
    }
  ]
})
export class Server {}

Sentinel

@tsed/redis (node-redis integration) currently documents and implements single + cluster modes. If you need Sentinel-specific behavior today, prefer @tsed/adapters-ioredis / @tsed/ioredis.

Typical Use Case

Used mainly with OIDC provider persistence, where adapter models (tokens, grants, codes) are stored in Redis.

typescript
import {OIDCRedisAdapter, RedisAdapter} from "@tsed/adapters-redis";

Test Isolation

When tests run in parallel, prefer keyPrefix isolation over Redis DB index rotation:

typescript
import {randomUUID} from "node:crypto";
import {Adapters} from "@tsed/adapters";
import {OIDCRedisAdapter} from "@tsed/adapters-redis";
import {DITest, inject} from "@tsed/di";
import {Property} from "@tsed/schema";
import {TestContainersRedis} from "@tsedio/testcontainers-redis";
import {beforeAll, beforeEach, afterAll, afterEach, describe, expect, it} from "vitest";

class AuthorizationCode {
  @Property()
  _id: string;

  @Property()
  uid: string;
}

describe("OIDC adapter isolation", () => {
  let keyPrefix: string;

  beforeAll(() => TestContainersRedis.startContainer());

  beforeEach(() => {
    keyPrefix = `test:${randomUUID()}`;
    return DITest.create({
      redis: [
        {
          name: "default",
          ...TestContainersRedis.getRedisOptions()
        }
      ]
    });
  });

  afterEach(() => DITest.reset());
  afterAll(() => TestContainersRedis.stopContainer());

  it("isolates data per test", async () => {
    const adapter = inject(Adapters).invokeAdapter<AuthorizationCode>({
      adapter: OIDCRedisAdapter,
      collectionName: "AuthorizationCode",
      model: AuthorizationCode,
      keyPrefix
    });

    await adapter.create({uid: "u1"});
    const items = await adapter.findAll();
    const keys = await (adapter as any).db.keys(adapter.prefix("AuthorizationCode:*"));

    expect(items.length).toBe(1);
    expect(keys.length).toBe(1);
    expect(keys[0]).toContain(adapter.prefix("AuthorizationCode:"));
  });
});

Released under the MIT License.