trpc adapter
See original GitHub issuehi again 😃
so in exploring trpc, they have some adapters, I took a stab at modifying their fetch adapter to work with hono, but I’d love some feedback on if this looks okay:
import { AnyRouter, inferRouterContext, resolveHTTPResponse } from '@trpc/server';
import { HTTPBaseHandlerOptions, HTTPRequest } from '@trpc/server/dist/http/internals/types';
import type { Context, } from 'hono';
import { StatusCode } from 'hono/utils/http-status';
export type HonoCreateContextFn<TRouter extends AnyRouter> = (opts: {
ctx: Context;
}) => inferRouterContext<TRouter> | Promise<inferRouterContext<TRouter>>;
export type HonoCreateContextOption<TRouter extends AnyRouter> =
unknown extends inferRouterContext<TRouter>
? {
/**
* @link https://trpc.io/docs/context
**/
createContext?: HonoCreateContextFn<TRouter>;
}
: {
/**
* @link https://trpc.io/docs/context
**/
createContext: HonoCreateContextFn<TRouter>;
};
export type HonoHandlerOptions<TRouter extends AnyRouter> = HTTPBaseHandlerOptions<
TRouter,
Request
> &
HonoCreateContextOption<TRouter>;
export type HonoHandlerRequestOptions<TRouter extends AnyRouter> = {
ctx: Context;
endpoint: string;
} & HonoHandlerOptions<TRouter>;
export async function honoRequestHandler<TRouter extends AnyRouter>(
opts: HonoHandlerRequestOptions<TRouter>
): Promise<Response> {
const createContext = async () => {
return opts.createContext?.({ ctx: opts.ctx });
};
const url = new URL(opts.ctx.req.url);
const path = url.pathname.slice(opts.endpoint.length + 1);
const req: HTTPRequest = {
query: url.searchParams,
method: opts.ctx.req.method,
headers: Object.fromEntries(opts.ctx.req.headers),
body: await opts.ctx.req.text(),
};
const result = await resolveHTTPResponse({
req,
createContext,
path,
router: opts.router,
batching: opts.batching,
responseMeta: opts.responseMeta,
onError(o) {
opts?.onError?.({ ...o, req: opts.ctx.req });
},
});
for (const [key, value] of Object.entries(result.headers ?? {})) {
if (typeof value === 'undefined') {
continue;
}
if (typeof value === 'string') {
opts.ctx.header(key, value);
continue;
}
for (const v of value) {
opts.ctx.header(key, v);
}
}
return opts.ctx.body(result.body, result.status as StatusCode);
}
Usage:
import { serve } from '@honojs/node-server';
import { Hono } from 'hono';
import { logger } from 'hono/logger';
import { initTRPC } from '@trpc/server';
import { honoRequestHandler } from './common/trpc';
const t = initTRPC.create();
const appRouter = t.router({
userById: t.procedure
.input((val: unknown) => {
if (typeof val === 'string') return val;
throw new Error(`Invalid input: ${typeof val}`);
})
.query(req => {
const { input } = req;
return { hello: 'world' };
}),
});
const app = new Hono();
app.use('*', logger());
app.get('/', c => c.text('working :~)'));
app.use('/trpc/*', c => {
return honoRequestHandler({
router: appRouter,
ctx: c,
endpoint: 'trpc/',
});
});
serve(app);
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:24 (3 by maintainers)
Top Results From Across the Web
Usage with Express - tRPC
tRPC includes an adapter for Express out of the box. This adapter lets you convert your tRPC router into an Express middleware. server.ts....
Read more >Official tRPC adapters
tRPC includes an adapter for the native Fetch API out of the box. This adapter lets you convert your tRPC router into a...
Read more >Usage with the Fetch API - tRPC
This adapter lets you convert your tRPC router into a Request handler that returns Response objects. Example apps. Description, Links. Cloudflare Workers ...
Read more >Usage with AWS Lambda through the API Gateway - tRPC
tRPC includes an adapter for API Gateway out of the box. This adapter lets you run your routes through the API Gateway handler....
Read more >Awesome tRPC Collection
Description, Link. tRPC-SvelteKit - SvelteKit tRPC extension, https://github.com/icflorescu/trpc-sveltekit. tRPC-Remix - Adapter for Remix ...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Ah, yes. It is also good to make it
@honojs/trpc-adapter
. Both are good.Since tRPC is so popular, I think it would be better to have it placed in that tRPC repository because it would be used by more people 😃
For example, we could create
@honojs/trpc-adapter
and put examples of Hono in tRPC examples.By the way, this is a different issue, but I am thinking of changing the way to manage Third-party Middleware. Specifically, I’m thinking of making it monorepo. In that case, it may take some time to create
@honojs/trpc-adapter
.I think this approach is great too, but I think trpc should also be supported, as they have a large ecosystem of tooling. For folks who aren’t using trpc already, this approach could get them very close to a similar experience.