honojs-middleware/packages/trpc-server
github-actions[bot] 319b955c74
Version Packages (#484)
2024-04-29 13:07:35 +09:00
..
src fix(trpc-server): Support asynchronous context creation (#482) 2024-04-29 13:04:45 +09:00
test fix(trpc-server): Support asynchronous context creation (#482) 2024-04-29 13:04:45 +09:00
CHANGELOG.md Version Packages (#484) 2024-04-29 13:07:35 +09:00
README.md feat(trpc): access hono context from trpc procedures (#458) 2024-04-27 11:46:09 +09:00
jest.config.js feat: introduce tRPC server middleware (#36) 2023-02-04 23:37:15 +09:00
package.json Version Packages (#484) 2024-04-29 13:07:35 +09:00
tsconfig.cjs.json feat: introduce tRPC server middleware (#36) 2023-02-04 23:37:15 +09:00
tsconfig.esm.json feat: introduce tRPC server middleware (#36) 2023-02-04 23:37:15 +09:00
tsconfig.json feat: introduce tRPC server middleware (#36) 2023-02-04 23:37:15 +09:00

README.md

tRPC Server Middleware for Hono

tRPC Server Middleware adapts a tRPC server as middleware for Hono. Hono works on almost any JavaScript runtime, including Cloudflare Workers, Deno, and Bun. So, with this middleware, the same code will run as tRPC server.

Install

npm install @hono/trpc-server

Usage

Router:

import { initTRPC } from '@trpc/server'
import { z } from 'zod'

const t = initTRPC.create()

const publicProcedure = t.procedure
const router = t.router

export const appRouter = router({
  hello: publicProcedure.input(z.string().nullish()).query(({ input }) => {
    return `Hello ${input ?? 'World'}!`
  }),
})

export type AppRouter = typeof appRouter

Hono app using tRPC Server Middleware:

import { Hono } from 'hono'
import { trpcServer } from '@hono/trpc-server' // Deno 'npm:@hono/trpc-server'
import { appRouter } from './router'

const app = new Hono()

app.use(
  '/trpc/*',
  trpcServer({
    router: appRouter,
  })
)

export default app

Client:

import { createTRPCProxyClient, httpBatchLink } from '@trpc/client'
import type { AppRouter } from './router'

const client = createTRPCProxyClient<AppRouter>({
  links: [
    httpBatchLink({
      url: 'http://localhost:8787/trpc',
    }),
  ],
})

console.log(await client.hello.query('Hono'))

Context

You can also access c.env from hono context from the trpc ctx. eg. here's an example using cloudflare D1 binding available as env.DB

import { initTRPC } from '@trpc/server'
import { z } from 'zod'

type Env = {
  DB: D1Database;
}
type HonoContext = {
  env: Env,
};

const t = initTRPC.context<HonoContext>().create()

const publicProcedure = t.procedure
const router = t.router

export const appRouter = router({
  usersCount: publicProcedure.query(({ input, ctx }) => {
    const result = await ctx.env.DB.prepare("SELECT count(*) from user;").all();
    return result.results[0].count;
  }),
})

export type AppRouter = typeof appRouter

For further control, you can optionally specify a createContext that in this case will receive the hono context as 2nd argument:

app.use(
  '/trpc/*',
  trpcServer({
    router: appRouter,
    createContext: (_opts, c) => ({
      // c is the hono context
      var1: c.env.MY_VAR1,
      var2: c.req.header('X-VAR2'),
    })
  })
)

Author

Yusuke Wada https://github.com/yusukebe

License

MIT