DI Integration
The cacheResolverDiFactory function creates an ICacheResolver whose underlying resolver is resolved from a DI container.
The returned proxy implements both ICacheResolver and ICache:
use(adapterName?)selects an adapter on the resolvedCacheResolver.- The
ICachemethods such asget,addandgetOrAdddelegate to the resolver's default adapter.
The proxy is wired to the container during container.init(). Create it before calling init(); calling use() or a cache method before the container is initialized throws an error.
Initial configuration
Set up the memory and Redis cache adapters, create the container, then register the CacheResolver and wrap it with cacheResolverDiFactory:
1. Set up the memory cache adapter
./samples/memory-cache-adapter.ts
import { MemoryCacheAdapter } from "eridu-tech/cache/memory-cache-adapter";
export const memoryCacheAdapter = new MemoryCacheAdapter();
2. Set up the Redis cache adapter
./samples/redis-cache-adapter.ts
import { RedisCacheAdapter } from "eridu-tech/cache/redis-cache-adapter";
import { SuperJsonSerde } from "eridu-tech/serde/super-json-serde";
import { Redis } from "ioredis";
export const redisCacheAdapter = new RedisCacheAdapter({
database: new Redis("YOUR_REDIS_CONNECTION_STRING"),
serde: new SuperJsonSerde(),
});
3. Create the dependency injection container
./samples/container.ts
import { Container } from "eridu-tech/di";
import { ExecutionContext } from "eridu-tech/execution-context";
import { AlsExecutionContextAdapter } from "eridu-tech/execution-context/als-execution-context-adapter";
export const executionContext = new ExecutionContext(
new AlsExecutionContextAdapter(),
);
export const container = new Container({ executionContext });
4. Register and initialize the cache resolver
./samples/cache-resolver-di-factory.ts
import { CacheResolver } from "eridu-tech/cache";
import { ProxyCacheResolver } from "eridu-tech/cache/di";
import { container } from "./container.js";
import { memoryCacheAdapter } from "./memory-cache-adapter.js";
import { redisCacheAdapter } from "./redis-cache-adapter.js";
type Adapters = "memory" | "redis";
const cacheResolver = new CacheResolver<Adapters>({
adapters: {
memory: memoryCacheAdapter,
redis: redisCacheAdapter,
},
defaultAdapter: "memory",
});
await cacheResolver.init();
container.registerValue({
token: CacheResolver,
value: cacheResolver,
});
// Create the proxy before container.init()
export const cache = new ProxyCacheResolver<Adapters>({
container,
resolverToken: CacheResolver,
});
await container.init();
Usage
1. Using the default adapter
./samples/cache-resolver-di-factory-default-adapter.ts
import { cache } from "./cache-resolver-di-factory.js";
// Uses the adapter configured as the default (memory)
await cache.add("user/jose@gmail.com", {
name: "Jose",
age: 20,
});
2. Specifying an adapter explicitly
./samples/cache-resolver-di-factory-specific-adapter.ts
import { cache } from "./cache-resolver-di-factory.js";
// Uses the Redis adapter
await cache.use("redis").add("user/jose@gmail.com", {
name: "Jose",
age: 20,
});
Using it with the middlewares
Because the proxy implements ICacheResolver, it can be passed straight to the cache middleware factories:
./samples/cache-resolver-di-factory-with-middleware.ts
import { withCacheFactory } from "eridu-tech/cache/middlewares";
import { use } from "eridu-tech/middleware";
import { TimeSpan } from "eridu-tech/time-span";
import { cache } from "./cache-resolver-di-factory.js";
const withCache = withCacheFactory(cache);
const fetchUser = async (userId: string): Promise<{ name: string }> => {
const response = await fetch(`/api/users/${userId}`);
return response.json();
};
const cachedFetchUser = use(
fetchUser,
withCache.use("redis")({
key: ([userId]) => `user:${userId}`,
ttl: TimeSpan.fromMinutes(10),
}),
);
await cachedFetchUser("123");
Further information
For further information refer to eridu-tech/cache API docs.