prisma-redis-middleware
This is a Prisma middleware used for caching and storing of Prisma queries in Redis (uses an in-memory LRU cache as
fallback storage).
Uses async-cache-dedupe.
Features
- Cache Invalidation
- Supports custom cache keys
- Cache persistance with Redis (uses an in-memory LRU cache as fallback)
- Caching multiple Prisma models each with a specific cache time
- Excluding certain Prisma models from being cached
- Excluding certain Prisma queries from being cached across all models
Supported Node.js versions
The latest versions of the following Node.js versions are tested and supported.
Default Cached Methods
Here is a list of all the Prisma methods that are currently cached by default in prisma-redis-middleware
.
- findUnique
- findUniqueOrThrow
- findFirst
- findFirstOrThrow
- findMany
- count
- aggregate
- groupBy
- findRaw
- aggregateRaw
queryRaw
is not cached as it's executed against the Prisma db itself and not a model. This Prisma middleware is used
for caching queries based on the models that they are executed against.
Quick Start
Install the package using npm
:
npm i --save-exact prisma-redis-middleware
You will also need to install and configure an external dependency for Redis
(for example: ioredis
or one that uses
a similar API) if you don't already have a Redis Client in your project.
npm i --save-exact ioredis @types/ioredis
Code Example (ESM / Import)
import Prisma from "prisma";
import { PrismaClient } from "@prisma/client";
import { createPrismaRedisCache } from "prisma-redis-middleware";
import Redis from "ioredis";
const redis = new Redis();
const prisma = new PrismaClient();
const cacheMiddleware: Prisma.Middleware = createPrismaRedisCache({
models: [
{ model: "User", excludeMethods: ["findMany"] },
{ model: "Post", cacheTime: 180, cacheKey: "article" },
],
storage: { type: "redis", options: { client: redis, invalidation: { referencesTTL: 300 }, log: console } },
cacheTime: 300,
excludeModels: ["Product", "Cart"],
excludeMethods: ["count", "groupBy"],
onHit: (key) => {
console.log("hit", key);
},
onMiss: (key) => {
console.log("miss", key);
},
onError: (key) => {
console.log("error", key);
},
});
prisma.$use(cacheMiddleware);
Code Example (Common JS / Require)
const Prisma = require("prisma");
const { PrismaClient } = require("@prisma/client");
const { createPrismaRedisCache } = require("prisma-redis-middleware");
const prisma = new PrismaClient();
const cacheMiddleware: Prisma.Middleware = createPrismaRedisCache({
models: [
{ model: "User", cacheTime: 60 },
{ model: "Post", cacheTime: 180 },
],
storage: { type: "memory", options: { invalidation: true, log: console } },
cacheTime: 300,
onHit: (key) => {
console.log("hit", key);
},
onMiss: (key) => {
console.log("miss", key);
},
onError: (key) => {
console.log("error", key);
},
});
prisma.$use(cacheMiddleware);
API
createPrismaRedisCache(opts)
Options:
-
onDedupe
: (optional) a function that is called every time a query is deduped.
-
onError
: (optional) a function that is called every time there is a cache error.
-
onHit
: (optional) a function that is called every time there is a hit in the cache.
-
onMiss
: (optional) a function that is called every time the result is not in the cache.
-
cacheTime
: (optional) (number) the default time (in ms) to use for models that don't have a cacheTime
value set.
Default is 0.
-
excludeModels
: (optional) (string) an array of models to exclude from being cached.
-
excludeMethods
: (optional) (string) an array of Prisma methods to exclude from being cached for all models.
-
models
: (optional) an array of Prisma models. Models options are:
-
model
: (required) string.
-
cacheKey
: (optional) string. Default is the model value.
-
cacheTime
: (optional) number (in ms).
-
excludeMethods
: (optional) (string) an array of Prisma methods to exclude from being cached for this model.
Example:
createPrismaRedisCache({
models: [
{ model: "User", cacheTime: 60 },
{ model: "Post", cacheKey: "article", excludeMethods: ["findFirst"] },
],
});
-
storage
: (optional) the storage options; default is { type: "memory" }
. Storage options are:
Debugging
You can pass functions for onMiss
, onHit
, onError
and onDedupe
to createPrismaRedisCache
which can then be
used to debug whether a Prisma query is being cached or not.
You can also pass a custom log
(pino or console) to the storage
option and async-cache-dedupe
will print debug
info as it queries, sets, expires and invalidates the cache. Note that the log
option can print out very verbose
output.