prisma-extension-redis
provides seamless integration with Prisma and Redis/Dragonfly databases, offering efficient caching mechanisms to improve data access times and overall application performance.
🚀 If prisma-extension-redis
proves helpful, consider giving it a star! ⭐ Star Me!
You can install prisma-extension-redis
using your preferred package manager:
Using npm:
npm install prisma-extension-redis
Using yarn:
yarn add prisma-extension-redis
Using pnpm:
pnpm add prisma-extension-redis
Using bun:
bun add prisma-extension-redis
Before setting up caching, initialize your Prisma client, Redis client config, and logger:
import pino from 'pino';
import { PrismaClient } from '@prisma/client';
import { Redis } from 'iovalkey';
import {SuperJSON} from 'superjson';
import {
CacheCase,
PrismaExtensionRedis,
type AutoCacheConfig,
type CacheConfig,
} from 'prisma-extension-redis';
// Prisma Client
const prisma = new PrismaClient();
// Redis client config
const client = {
host: process.env.REDIS_HOST_NAME, // Redis host
port: process.env.REDIS_PORT, // Redis port
};
// Create a logger using pino (optional)
const logger = pino();
auto
settings enable automated caching for read operations with flexible customization.
const auto: AutoCacheConfig = {
excludedModels: ['Post'], // Models excluded from auto-caching
excludedOperations: ['findFirst', 'count', 'findMany'], // Operations excluded from auto-caching
models: [
{
model: 'User', // Model-specific auto-cache settings
excludedOperations: ['count'], // Operations to exclude
ttl: 10, // Time-to-live (TTL) for cache in seconds
stale: 5, // Stale time in seconds
},
],
ttl: 30, // Default TTL for cache in seconds
};
Note:
ttl
and stale
values to define caching duration.The cache client configuration is necessary to enable caching, either automatically or manually.
const config: CacheConfig = {
ttl: 60, // Default Time-to-live for caching in seconds
stale: 30, // Default Stale time after ttl in seconds
auto, // Auto-caching options (configured above)
logger, // Logger for cache events (configured above)
transformer: {
// Custom serialize and deserialize function for additional functionality if required
deserialize: data => SuperJSON.parse(data),
serialize: data => SuperJSON.stringify(data),
},
type: 'JSON', // Redis cache type, whether you prefer the data to be stored as JSON or STRING in Redis
cacheKey: { // Inbuilt cache key configuration
case: CacheCase.SNAKE_CASE, // Select a cache case conversion option for generated keys from CacheCase
delimiter: '*', // Delimiter for keys (default value: ':')
prefix: 'awesomeness', // Cache key prefix (default value: 'prisma')
},
};
Note: Cache case conversion strips all non alpha numeric characters
Now, extend your Prisma client with caching capabilities using prisma-extension-redis
:
const extendedPrisma = prisma.$extends(
PrismaExtensionRedis({ config, client })
);
With auto-caching, read operations (e.g., findUnique
, findMany
) are cached automatically based on the defined configuration.
Basic Example:
// Cached automatically based on auto-cache settings
extendedPrisma.user.findUnique({
where: { id: userId },
});
// Manually enable cache for a query
extendedPrisma.user.findUnique({
where: { id: userId },
cache: true, // Toggle caching on
});
// Disable cache for specific query
extendedPrisma.user.findFirst({
where: { id: userId },
cache: false, // Toggle caching off
});
Note:
auto-cache
is set to false
and cache
is set to true
for the query, the default values from the cache configuration will be applied.cache
is set to false
and auto-cache
is set to true
, the query will not be cached.getKey
For greater control over caching, generate custom cache keys and TTL settings.
Example with Custom Cache Key:
const customKey = extendedPrisma.getKey({ params: [{ prisma: 'User' }, { id: userId }] });
extendedPrisma.user.findUnique({
where: { id: userId },
cache: { ttl: 5, key: customKey }, // Custom TTL and cache key
});
Cache invalidation ensures data consistency by removing or updating cached data when changes occur in the database.
Example of Cache Invalidation:
// Invalidate cache when updating a user's information
extendedPrisma.user.update({
where: { id: userId },
data: { username: newUsername },
uncache: {
uncacheKeys: [
extendedPrisma.getKey({ params: [{ prisma: 'User' }, { id: userId }] }), // Specific key to invalidate
getKeyPattern({ params: [{ prisma: '*' }, { id: userId }]}), // Pattern for wildcard invalidation
getKeyPattern({ params: [{ prisma: 'Post' }, { id: userId }, { glob: '*' }]}), // Use glob for more complex patterns
],
hasPattern: true, // Use pattern matching for invalidation
},
});
Explanation of Cache Invalidation:
uncacheKeys
: Specifies the keys or patterns to be invalidated.hasPattern
: Indicates if wildcard patterns are used for key matching.getKey
: Generates a unique key for caching queries from provided key context parameters.getAutoKey
: Generates a unique key for auto-caching queries, based on query parameters.getKeyPattern
: Creates patterns for more complex invalidation scenarios, using wildcards.Redis.JSON
must be enabled to use JSON type cache (by default, it is enabled in Dragonfly).iovalkey
package is used for Redis connectivity.micromatch
is used for patter matching for keys.object-code
is used for generating unique hash in auto-caching keys.lodash-es
is used for CacheCase logic in key management.prisma-extension-redis
offers an efficient and powerful way to manage caching in Prisma-based applications. By leveraging both automatic and custom caching, you can optimize your application's performance while maintaining data consistency.
Upgrade to prisma-extension-redis
for an optimized caching strategy and contribute to its growth by starring the repository if you find it useful!