Split tRPC Router

JavaScript pattern

Split a tRPC router into multiple files, one per route.

Splits trpc router

BEFORE
// @filename: js/trpcRouter.server.ts
import { initTRPC, TRPCError } from '@trpc/server';
import * as Sentry from '@sentry/remix';
import { Context } from './trpcContext.server';
import { db } from '../db';

export const t = initTRPC.context<Context>().create();

function fixNames(text: string) {
  return text.trim().replace(/[^a-zA-Z0-9]/g, '_');
}

const proc = t.procedure.use(
  t.middleware(
    Sentry.Handlers.trpcMiddleware({
      attachRpcInput: true,
    }),
  ),
);

export const appRouter = t.router({
  hello: proc.input(z.object({ name: z.string() })).query(async ({ input }) => {
    return { text: `Hello ${input.name}` };
  }),
  goodbye: proc.input(z.object({ name: z.string() })).query(async ({ input }) => {
    await db.remove(input.name);
    return { text: `Goodbye ${input.name}` };
  }),
});

export type AppRouter = typeof appRouter;
AFTER
// @filename: js/trpcRouter.server.ts

import { helloRoute } from './hello.route';
import { goodbyeRoute } from './goodbye.route';
import { t } from './middleware';

export const appRouter = t.router({
  hello: helloRoute,
  goodbye: goodbyeRoute,
});

export type AppRouter = typeof appRouter;
// @filename: js/goodbye.route.ts
import { proc } from './middleware';
import { db } from '../db';
export const goodbyeRoute = proc.input(z.object({ name: z.string() })).query(async ({ input }) => {
  await db.remove(input.name);
  return { text: `Goodbye ${input.name}` };
});
// @filename: js/hello.route.ts
import { proc } from './middleware';
export const helloRoute = proc.input(z.object({ name: z.string() })).query(async ({ input }) => {
  return { text: `Hello ${input.name}` };
});
// @filename: js/middleware.ts
import { initTRPC } from '@trpc/server';
import * as Sentry from '@sentry/remix';
import { Context } from './trpcContext.server';
export const t = initTRPC.context<Context>().create();
export const proc = t.procedure.use(
  t.middleware(
    Sentry.Handlers.trpcMiddleware({
      attachRpcInput: true,
    }),
  ),
);