tRPC
This is how your API handler would typically look like:
import express from "express";
import * as fs from "node:fs/promises";
import { z } from "zod";
import { initTRPC } from "@trpc/server";
import { createExpressMiddleware } from "@trpc/server/adapters/express";
import type { Request } from "express";
import { bootstrapAuth, getUser } from "./auth"; // See below
function startExpressTrpcServer() {
bootstrapAuth({
implementation: "real", // or "mock", see: https://docs.oidc-spa.dev/v/v8/integration-guides/backend-token-validation/mock-modes
issuerUri: process.env.OIDC_ISSUER_URI!,
expectedAudience: process.env.OIDC_AUDIENCE
});
const app = express();
/**
* Key idea: Wether you use use Express or something else
* as underlying HTTP framework, just expose whatever the
* request object representation is to the global context.
* oidc-spa will be able to extract the auth context from it.
*/
const createContext = ({ req }: { req: Request }) => ({ req });
type Context = ReturnType<typeof createContext>;
const t = initTRPC.context<Context>().create();
const appRouter = t.router({
todos: t.procedure.query(async ({ ctx }) => {
const user = await getUser({ req: ctx.req });
const json = await fs.readFile(
`todos_${user.id}.json`,
"utf8"
);
return JSON.parse(json);
}),
todosForSupportStaff: t.procedure
.input(z.object({ userId: z.string() }))
.query(async ({ ctx, input }) => {
// Will reject the request if user making the request
// doesn't have "support-staff" role
await getUser({ req: ctx.req, requiredRole: "support-staff" });
const json = await fs.readFile(`todos_${input.userId}.json`, "utf8");
return JSON.parse(json);
})
});
app.use(
"/trpc",
// Needed for tRPC POST requests.
express.json(),
createExpressMiddleware({
router: appRouter,
createContext
})
);
app.listen(parseInt(process.env.PORT ?? "3000"), () => {
console.log("Server running");
});
}Let's see how to export the utils to make it happen:
Last updated
Was this helpful?