-
Notifications
You must be signed in to change notification settings - Fork 9.5k
feat: prisma DB multi-tenancy (cal.eu) #21364
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 1 Skipped Deployment
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've tried to cover the main entrypoints with re-usable wrappers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same for pages
apps/web/middleware_prisma-test.ts
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a real middleware, but an example on how this would work in middleware. We could attach the tenant to headers
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would be the main client storage. This plays nice with serverless and we move away to global hacks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrapper for API routes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wrapper for SSR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We centralize tenants pairing here
…ion tools Co-Authored-By: [email protected] <[email protected]>
…ut prop drilling Co-Authored-By: [email protected] <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome reading through this PR @zomars.
I was wondering for the routes I know we need to have the withMultiTenantPrisma
wrapper but I'm curious why cannot we use Nextjs middleware here for those routes? Would invoking that function in the middleware set the AsyncLocalStorage
for the endpoint handler?
export function getPrisma(tenant: Tenant, options?: Prisma.PrismaClientOptions) { | ||
if (process.env.NODE_ENV === "test") { | ||
const url = tenantToDatabaseUrl[tenant]; | ||
if (!url) throw new Error(`Missing DB URL for tenant: ${tenant}`); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Now that we have two database URLs, should we create an alert if this error hits or the one on line 78? Just in case something happens with our config?
I'm wondering if we can also utilize middleware here so we don't need to add more boiler plate code |
AsyncLocalStorage is part of the Node.js async_hooks module, which is not available in the Edge Runtime. So no middleware. @joeauyeung |
Signed-off-by: Omar López <[email protected]>
Signed-off-by: Omar López <[email protected]>
E2E results are ready! |
What does this PR do?
This pull request introduces multi-tenancy support for Prisma by implementing tenant-aware database connections and refactoring existing routes and utilities to utilize the new multi-tenant architecture. The main changes include the creation of a
TenantAwarePrismaService
, updates to API routes to use tenant-aware Prisma wrappers, and modifications to the Prisma initialization logic.TODOs
runWithTenants
, possibly atlayout.tsx
level so we do it only once..eu
domains via env var.Multi-tenancy implementation:
apps/api/v2/src/modules/prisma/tenant-aware-prisma.service.ts
: Added a newTenantAwarePrismaService
to dynamically configure Prisma connections based on the tenant derived from the request's host header. This service ensures tenant-specific database URLs are used.packages/prisma/index.ts
: Refactored Prisma initialization to use a proxy that dynamically selects the appropriate tenant-aware Prisma instance or throws an error if accessed outside of a tenant-aware context. IntroducedgetPrisma
andgetTenantAwarePrisma
utilities for tenant-specific database connections. [1] [2]Updates to API routes:
API route refactoring: Updated multiple API routes (e.g.,
calendar-cache
,credentials
,selected-calendars
,tasks
) to wrap handlers withwithMultiTenantPrisma
, ensuring tenant-aware database operations. [1] [2] [3] [4] [5] [6]New tenant-aware routes: Added new tenant-aware API routes for testing and demonstration purposes, such as
prisma-test
andtenant-aware-example
. These routes showcase fetching tenant-specific data using the new multi-tenant setup. [1] [2]Utility and library updates:
packages/features/auth/lib/getServerSession.ts
: Updated thegetServerSession
function to run within a tenant-aware context using therunWithTenants
utility, ensuring tenant-specific session handling. [1] [2]packages/features/calendar-cache/api/cron.ts
: Refactored thecalendar-cache
cron handler to useNextRequest
andNextResponse
for better compatibility with the tenant-aware architecture. [1] [2]Cleanup and deprecations:
Removed old Prisma extensions: Deprecated custom Prisma extensions and middleware in favor of the new tenant-aware architecture. Simplified the Prisma client initialization logic. [1] [2]
Removed unused exports: Removed legacy exports like
default
from certain files (e.g.,calendar-cache/cron.ts
).This refactor significantly improves the application's scalability by enabling multi-tenancy while maintaining backward compatibility for existing routes.
Visual Demo (For contributors especially)
A visual demonstration is strongly recommended, for both the original and new change (video / image - any one).
Video Demo (if applicable):
Image Demo (if applicable):
Mandatory Tasks (DO NOT REMOVE)
How should this be tested?
Checklist
Summary by mrge
Added an initial Prisma client store to support multi-tenant database connections based on request host.