Skip to content

Instantly share code, notes, and snippets.

@exAspArk
Last active December 20, 2023 16:38
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save exAspArk/d7d5774276b7981931400781608e4770 to your computer and use it in GitHub Desktop.
Save exAspArk/d7d5774276b7981931400781608e4770 to your computer and use it in GitHub Desktop.
Prisma Extension with Express.js HTTP Request Context
import { Request, Response, NextFunction } from "express";
import { AsyncLocalStorage } from "node:async_hooks";
import { PrismaClient } from '@prisma/client';
const ASYNC_LOCAL_STORAGE = new AsyncLocalStorage();
export const setContext = (callback: (req: Request) => any) => {
return (req: Request, _res: Response, next: NextFunction) => {
const context = callback(req);
// Set context for current request
ASYNC_LOCAL_STORAGE.run(context, () => {
next(); // Run next middleware
});
};
};
export const prismaWithContext = new PrismaClient().$extends({
query: {
$allModels: {
async $allOperations({ query, args }: any) {
const context = ASYNC_LOCAL_STORAGE.getStore()
// Do something with "context"
// ^ This approach is used by https://github.com/BemiHQ/prisma for automatic
// database change tracking stitched with customized request-specific context
// without the need to manually update DB queries or wrap them in transactions
return query(args)
},
},
},
})
import express from "express";
import { setContext } from "./prisma-context";
const app = express();
const port = 3000;
app.use(
setContext((req: Request) => ({
userId: req.user?.id,
apiEndpoint: req.url,
params: req.body,
}))
);
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment