Package Exports
- prisma-multi-tenant
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (prisma-multi-tenant) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
prisma-multi-tenant
🧭 Use Prisma as a multi-tenant provider with Apollo Server or Yoga
What's a multi-tenant application?
A multi-tenant application is when a single instance of your application runs on a server and serves multiple tenants.
With a multi-tenant architecture, a software application is designed to provide every tenant a dedicated share of the instance - including its data, configuration, user management, tenant individual functionality and non-functional properties.
For example, you could run a social-network for companies, where each company would have it's own data and users.
Why is Prisma great for multi-tenancy?
Prisma handles services mapped to individual databases. You can use services to have multiple different applications, or your could create a service for each of your tenant.
A service is defined by a name and a stage. (e.g. company_a/dev, company_a/prod, company_b/pre-prod, company_b/prod)
Why do I need prisma-multi-tenant?
Because Prisma Client only handles a single service. If you want your GraphQL Server (Apollo or Yoga) to handle multiple services seamlessly, you should use prisma-multi-tenant!
Installation
npm install prisma-multi-tenantBasic usage
The following example is using Prisma Client. You will find instructions for prisma-binding after this example.
/* In your backend's main file */
const { MultiTenant } = require('prisma-multi-tenant')
const { Prisma } = require('./generated/prisma-client')
const { ApolloServer } = require('apollo-server')
const multiTenant = new MultiTenant({
instanciate: (name, stage) =>
new Prisma({
endpoint: `https://localhost:4000/${name}/${stage}`
})
})
const server = new ApolloServer({
/* ..., */
context: ctx => ({
...ctx,
prisma: multiTenant.current(ctx.req) // or ctx.request if you use GraphQL-Yoga
})
})
/* In your resolvers */
module.exports = {
Query: {
users: (_, args, ctx) => ctx.prisma.users(args)
}
}Then, from your frontend, you can use a prisma-service HTTP header with [name]/[stage] in your GraphQL operations to choose which service to target.
With prisma-binding
If you use prisma-binding, you need to slightly change the previous code:
const { MultiTenant } = require('prisma-multi-tenant')
const { Prisma } = require('prisma-binding')
const multiTenant = new MultiTenant({
instanciate: (name, stage) =>
new Prisma({
typeDefs: './path/to/typedef.graphql',
endpoint: `https://localhost:4000/${name}/${stage}`
})
/* ... */
})
/* ... */Constructor options
The constructor of MultiTenant accepts an option object argument with the following attributes:
interface MultiTenantOptions {
/* Returns a PrismaClient (or prisma-binding) instance given a name and a stage */
instanciate: (name: string, stage: string) => PrismaInstance
/* Extracts the name and stage from the Request object */
nameStageFromReq: (req: Object) => [string, string]
}
const defaultOptions: MultiTenantOptions = {
instanciate: () => ({}),
nameStageFromReq: (req: Object) => req.headers['prisma-service'].split('/')
}By default, the
name/stageof the service will be extracted from theprisma-serviceHTTP header, but you can extract it anyway you want from the Request (url, body, another header, ...)
Credits
🙌 Thanks to @antoinecarat for the reviews of this library