Last active
June 14, 2022 17:25
-
-
Save daniellwdb/0c2dba8b5807393ac9bf1f48429c1f06 to your computer and use it in GitHub Desktop.
Prisma cache middleware
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { Prisma } from "@prisma/client" | |
import { redis } from "../redis" | |
type CacheMiddlewareOptions = { | |
model: Prisma.ModelName | |
action: Prisma.PrismaAction | |
keys?: string[] | |
defaultValues?: Record<string, unknown> | |
ttlInSeconds: number | |
} | |
export const cacheMiddleware = ({ | |
model, | |
action, | |
keys, | |
defaultValues, | |
ttlInSeconds, | |
}: CacheMiddlewareOptions): Prisma.Middleware => async (params, next) => { | |
if (params.model !== model || action !== params.action) { | |
return next(params) | |
} | |
// Return early if caching should only happen when specific keys are selected | |
// but the current query does not include all of them | |
if (keys) { | |
const selectedKeys = Object.keys(params.args.select) | |
const match = selectedKeys.every(key => keys.includes(key)) | |
if (!match) { | |
return next(params) | |
} | |
} | |
let result | |
const key = `${params.model}:${params.action}:${JSON.stringify(params.args)}` | |
await redis.del(key) | |
result = await redis.hgetall(key) | |
if (!Object.keys(result).length) { | |
try { | |
result = await next(params) | |
} catch (err) { | |
if (err.name !== "NotFoundError") { | |
throw err | |
} | |
if (!defaultValues) { | |
throw new Error( | |
`${err.message}. Either handle the case of undefined by removing \`rejectOnNotFound\` or pass in \`defaultValues\`.` | |
) | |
} | |
result = defaultValues | |
} | |
await redis.hmset(key, result) | |
if (ttlInSeconds) { | |
redis.expire(key, ttlInSeconds) | |
} | |
} | |
return result | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
prisma.$use( | |
cacheMiddleware({ | |
model: "Guild", | |
action: "findUnique", | |
defaultValues: { language: "nl", prefix: "!a" }, | |
ttlInSeconds: 10, | |
}) | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const config = await prisma.guild.findUnique({ | |
where: { | |
id: guild.id, | |
}, | |
select: { | |
prefix: true, | |
language: true, | |
}, | |
rejectOnNotFound: true, | |
}) | |
config.prefix // Not null, errors if defaultValues is not present |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment