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 redissh
yarn add @tsed/adapters-redis @tsed/redis redissh
pnpm add @tsed/adapters-redis @tsed/redis redissh
bun add @tsed/adapters-redis @tsed/redis redisExports
RedisAdapterOIDCRedisAdapterRedisAdaptersSettings(globalTsED.AdaptersOptionsextension)
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:"));
});
});