Sharing Logic Across TRPC Procedures

I've got multiple procedures that need to share logic. For example, I've got a query and a mutation that both return a lastUpdatedBy field. Instead of returning the user id, I return their name. Technically, I've been able to write the code within both the query and mutation, but I'm struggling to find a way to share that logic. The main issue is really a Typescript one where I can't figure out how to
getSomething: protectedProcedure
.input(z.object({ id: z.string() }))
.query(async ({ ctx, input }) => {
let something = await ctx.db.somethings.findUnique({
where: {
id: parseInt(input.id),
},
});

// here's where I want to write some shared logic
something = await processSomething({ something, db: ctx.db });
getSomething: protectedProcedure
.input(z.object({ id: z.string() }))
.query(async ({ ctx, input }) => {
let something = await ctx.db.somethings.findUnique({
where: {
id: parseInt(input.id),
},
});

// here's where I want to write some shared logic
something = await processSomething({ something, db: ctx.db });
The challenge I'm stuck on is figuring out the types in my util. I was able to get the prisma types, but not the something types.
type Props = {
db: PrismaClient<Prisma.PrismaClientOptions, never, DefaultArgs>;
something: ???
}
function processSomething({something, db}: Props) {}
type Props = {
db: PrismaClient<Prisma.PrismaClientOptions, never, DefaultArgs>;
something: ???
}
function processSomething({something, db}: Props) {}
I've tried this approach https://trpc.io/docs/client/vanilla/infer-types with something like
type RouterOutput = inferRouterOutputs<AppRouter>;
type Home = RouterOutput["something"]["getSomething"];
type RouterOutput = inferRouterOutputs<AppRouter>;
type Home = RouterOutput["something"]["getSomething"];
But that produces an error
'something' is referenced directly or indirectly in its own type annotation.
Any suggestions? thanks!
Inferring Types | tRPC
It is often useful to access the types of your API within your clients. For this purpose, you are able to infer the types contained in your AppRouter.
2 Replies
GrizzlyMg
GrizzlyMg4mo ago
If I get what you meant, maybe this something you want todo? https://trpc.io/docs/server/server-side-calls
Server Side Calls | tRPC
You may need to call your procedure(s) directly from the same server they're hosted in, createCallerFactory() can be used to achieve this. This is useful for server-side calls and for integration testing of your tRPC procedures.
noynek2242
noynek22424mo ago
Thanks. Turns out I was basically doing what it says to do in that server-side-calls section. The part I was missing was finding the right types from Prisma so I could pass around the DB items. The trick there was to import
import { type Prisma } from "@prisma/client";
import { type Prisma } from "@prisma/client";
and then explore those definitions until I found one that made sense. Thanks