Using With tRPC
tRPC is a fantastic library that magically turns server-side procedures into client-callable functions without requiring you to provide any official contract. The popular T3 stack promotes the combo of Prisma + tRPC for achieving type safety from your frontend all the way down to the database.
ZenStack makes things even easier by automatically generating tRPC routers from the ZModel schema. You can use the generated routers together with an enhanced Prisma client; since the Prisma client has the ability to enforce access policies, there is no need to implement authorization code anymore.
Details​
If you haven't initialized your tRPC project with ZenStack, run the following command to do it:
bash
npx zenstack@latest init
bash
npx zenstack@latest init
The command installs a few NPM dependencies and copies Prisma schema from prisma/schema.prisma
to schema.zmodel
. Moving forward, you will keep updating this file, and prisma/schema.prisma
will be automatically generated from it.
You can enable tRPC router generation with the @zenstackhq/trpc
plugin.
First install the trpc package:
bash
npm install @zenstackhq/trpc
bash
npm install @zenstackhq/trpc
/schema.zmodelprisma
plugin trpc {provider = '@zenstackhq/trpc'output = 'src/server/routers/generated'}
/schema.zmodelprisma
plugin trpc {provider = '@zenstackhq/trpc'output = 'src/server/routers/generated'}
When you run zenstack generate
again, you should find a bunch of tRPC routers generated in the output folder, one per each data model. A createRouter
helper function is also generated, which returns a router instance for all models. You can use it as your top-level tRPC router, or merge it with other routers to form a more complex setup.
/src/server/routers/_app.tsts
import { createRouter } from './generated/routers';const t = initTRPC.context<Context>().create();export const appRouter = createRouter(t.router, t.procedure);export type AppRouter = typeof appRouter;
/src/server/routers/_app.tsts
import { createRouter } from './generated/routers';const t = initTRPC.context<Context>().create();export const appRouter = createRouter(t.router, t.procedure);export type AppRouter = typeof appRouter;
If your data model uses field types that're not JSON-serializable, you should set up tRPC to use superjson data transformer.
NOTE: The ZenStack trpc plugin is based on the awesome work by Omar Dulaimi.