tRPC Integration
This guide explains how to integrate oRPC with tRPC, allowing you to leverage oRPC features in your existing tRPC applications.
Installation
npm install @orpc/trpc@betayarn add @orpc/trpc@betapnpm add @orpc/trpc@betabun add @orpc/trpc@betadeno add npm:@orpc/trpc@betaOpenAPI Support
By converting a tRPC router to an oRPC router, you can utilize most oRPC features, including OpenAPI specification generation and request handling.
import { toORPCRouter } from '@orpc/trpc'
const orpcRouter = toORPCRouter(trpcRouter)WARNING
For OpenAPI features to work, define OpenAPI metadata under the '~openapi' key in your tRPC meta, typed with OpenAPIMeta from @orpc/openapi:
import type { OpenAPIMeta } from '@orpc/openapi'
interface Meta {
'~openapi'?: OpenAPIMeta
}
export const t = initTRPC.context<Context>().meta<Meta>().create()
const example = t.procedure
.meta({ '~openapi': { path: '/hello', summary: 'Hello procedure' } })
.input(z.object({ name: z.string() }))
.query(({ input }) => {
return `Hello, ${input.name}!`
})If you prefer keeping the metadata under a different key, use the mapMeta option to expose it during conversion:
interface Meta {
route?: OpenAPIMeta
}
const orpcRouter = toORPCRouter(trpcRouter, {
mapMeta: meta => ({ ...meta, '~openapi': meta.route }),
})Specification Generation
const generator = new OpenAPIGenerator({
converters: [
new ZodToJsonSchemaConverter(), // <-- if you use Zod
new ValibotToJsonSchemaConverter(), // <-- if you use Valibot
new ArkTypeToJsonSchemaConverter(), // <-- if you use ArkType
],
})
const spec = await generator.generate(orpcRouter, {
base: {
info: {
title: 'My App',
version: '0.0.0',
},
},
})INFO
Learn more about oRPC OpenAPI Specification Generation.
Request Handling
const handler = new OpenAPIHandler(orpcRouter, {
plugins: [new CORSHandlerPlugin()],
})
export async function fetch(request: Request) {
const { matched, response } = await handler.handle(request, {
prefix: '/api',
context: {} // Add initial context if needed
})
return response ?? new Response('Not Found', { status: 404 })
}INFO
Learn more about oRPC OpenAPI Handler.
Error Formatting
The toORPCRouter does not support tRPC Error Formatting. You should catch errors and format them manually using interceptors:
const handler = new OpenAPIHandler(orpcRouter, {
interceptors: [
async ({ next }) => {
try {
return await next()
}
catch (error) {
if (
error instanceof ORPCError
&& error.cause instanceof TRPCError
&& error.cause.cause instanceof z.ZodError
) {
throw new ORPCError('UNPROCESSABLE_CONTENT', {
message: z.prettifyError(error.cause.cause),
data: z.flattenError(error.cause.cause),
cause: error.cause.cause,
})
}
throw error
}
},
],
})
