feat: introduce tRPC server middleware (#36)
* feat: introduce tRPC server middleware * chore: add changesetpull/37/head
parent
f05c6094d2
commit
e7c60b3492
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
'@hono/trpc-server': patch
|
||||
---
|
||||
|
||||
Initial release
|
|
@ -0,0 +1,25 @@
|
|||
name: ci-trpc-server
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'packages/trpc-server/**'
|
||||
pull_request:
|
||||
branches: ['*']
|
||||
paths:
|
||||
- 'packages/trpc-server/**'
|
||||
|
||||
jobs:
|
||||
ci:
|
||||
runs-on: ubuntu-latest
|
||||
defaults:
|
||||
run:
|
||||
working-directory: ./packages/trpc-server
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 18.x
|
||||
- run: yarn install --frozen-lockfile
|
||||
- run: yarn build
|
||||
- run: yarn test
|
|
@ -12,6 +12,7 @@
|
|||
"build:graphql-server": "yarn workspace @hono/graphql-server build",
|
||||
"build:sentry": "yarn workspace @hono/sentry build",
|
||||
"build:firebase-auth": "yarn workspace @hono/firebase-auth build",
|
||||
"build:trpc-server": "yarn workspace @hono/trpc-server build",
|
||||
"build": "run-p build:*"
|
||||
},
|
||||
"license": "MIT",
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
# tRPC Adapter Middleware for Hono
|
||||
|
||||
## Usage
|
||||
|
||||
```ts
|
||||
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
|
@ -1,30 +0,0 @@
|
|||
{
|
||||
"name": "@honojs/trpc-adapter",
|
||||
"version": "0.0.0",
|
||||
"description": "tRPC Adapter Middleware for Hono",
|
||||
"main": "dist/index.js",
|
||||
"types": "dist/index.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"build": "rimraf dist && tsc",
|
||||
"prerelease": "yarn build && yarn test",
|
||||
"release": "yarn publish"
|
||||
},
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org",
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/honojs/middleware.git"
|
||||
},
|
||||
"homepage": "https://honojs.dev",
|
||||
"dependencies": {
|
||||
"hono": "^2.3.0"
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
import { Hono } from 'hono'
|
||||
import { trpcAdapter } from '../src'
|
||||
|
||||
describe('tRPC Adapter Middleware', () => {
|
||||
const app = new Hono()
|
||||
|
||||
app.use('/trpc/*', trpcAdapter())
|
||||
app.get('/trpc', (c) => c.text('Here is dummy endpoint'))
|
||||
|
||||
it('Should return 200 response', async () => {
|
||||
const res = await app.request('http://localhost/trpc')
|
||||
expect(res).not.toBeNull()
|
||||
expect(res.status).toBe(200)
|
||||
})
|
||||
})
|
|
@ -1,7 +0,0 @@
|
|||
import type { Handler } from 'hono'
|
||||
|
||||
export const trpcAdapter = (): Handler => {
|
||||
return async (_c, next) => {
|
||||
await next()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
# tRPC Server Middleware for Hono
|
||||
|
||||
tRPC Server Middleware adapts a [tRPC](https://trpc.io) 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:
|
||||
|
||||
```ts
|
||||
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:
|
||||
|
||||
```ts
|
||||
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:
|
||||
|
||||
```ts
|
||||
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'))
|
||||
```
|
||||
|
||||
## Author
|
||||
|
||||
Yusuke Wada <https://github.com/yusukebe>
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
|
@ -0,0 +1,42 @@
|
|||
{
|
||||
"name": "@hono/trpc-server",
|
||||
"version": "0.0.0",
|
||||
"description": "tRPC Server Middleware for Hono",
|
||||
"main": "dist/cjs/index.js",
|
||||
"module": "dist/esm/index.js",
|
||||
"types": "dist/esm/index.d.ts",
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"test": "jest",
|
||||
"build:cjs": "tsc -p tsconfig.cjs.json",
|
||||
"build:esm": "tsc -p tsconfig.esm.json",
|
||||
"build": "rimraf dist && yarn build:cjs && yarn build:esm",
|
||||
"prerelease": "yarn build && yarn test",
|
||||
"release": "yarn publish"
|
||||
},
|
||||
"license": "MIT",
|
||||
"private": false,
|
||||
"publishConfig": {
|
||||
"registry": "https://registry.npmjs.org",
|
||||
"access": "public"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/honojs/middleware.git"
|
||||
},
|
||||
"homepage": "https://honojs.dev",
|
||||
"peerDependencies": {
|
||||
"@trpc/server": "^10.10.0",
|
||||
"hono": "^2.7.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@trpc/server": "^10.10.0",
|
||||
"hono": "^2.7.5",
|
||||
"zod": "^3.20.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
import type { AnyRouter } from '@trpc/server'
|
||||
import { fetchRequestHandler } from '@trpc/server/adapters/fetch'
|
||||
import type { MiddlewareHandler } from 'hono'
|
||||
|
||||
type tRPCOptions = {
|
||||
endpoint?: string
|
||||
router: AnyRouter
|
||||
}
|
||||
|
||||
export const trpcServer = ({ router, endpoint = '/trpc' }: tRPCOptions): MiddlewareHandler => {
|
||||
return async (c) => {
|
||||
const res = fetchRequestHandler({
|
||||
endpoint: endpoint,
|
||||
req: c.req,
|
||||
router: router,
|
||||
})
|
||||
return res
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
import { initTRPC } from '@trpc/server'
|
||||
import { Hono } from 'hono'
|
||||
import { z } from 'zod'
|
||||
import { trpcServer } from '../src'
|
||||
|
||||
describe('tRPC Adapter Middleware', () => {
|
||||
const t = initTRPC.create()
|
||||
|
||||
const publicProcedure = t.procedure
|
||||
const router = t.router
|
||||
|
||||
const appRouter = router({
|
||||
hello: publicProcedure.input(z.string().nullish()).query(({ input }) => {
|
||||
return `Hello ${input ?? 'World'}`
|
||||
}),
|
||||
})
|
||||
|
||||
const app = new Hono()
|
||||
|
||||
app.use(
|
||||
'/trpc/*',
|
||||
trpcServer({
|
||||
router: appRouter,
|
||||
})
|
||||
)
|
||||
|
||||
it('Should return 200 response', async () => {
|
||||
const searchParams = new URLSearchParams({
|
||||
input: JSON.stringify({ '0': 'Hono' }),
|
||||
batch: '1',
|
||||
})
|
||||
const req = new Request(`http://localhost/trpc/hello?${searchParams.toString()}`)
|
||||
const res = await app.request(req)
|
||||
expect(res.status).toBe(200)
|
||||
expect(await res.json()).toEqual([
|
||||
{
|
||||
result: {
|
||||
data: 'Hello Hono',
|
||||
},
|
||||
},
|
||||
])
|
||||
})
|
||||
})
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "CommonJS",
|
||||
"declaration": false,
|
||||
"outDir": "./dist/cjs"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"extends": "./tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"module": "ESNext",
|
||||
"declaration": true,
|
||||
"outDir": "./dist/esm"
|
||||
}
|
||||
}
|
|
@ -2,7 +2,6 @@
|
|||
"extends": "../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"rootDir": "./src",
|
||||
"outDir": "./dist",
|
||||
},
|
||||
"include": [
|
||||
"src/**/*.ts"
|
17
yarn.lock
17
yarn.lock
|
@ -1511,6 +1511,11 @@
|
|||
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf"
|
||||
integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==
|
||||
|
||||
"@trpc/server@^10.10.0":
|
||||
version "10.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@trpc/server/-/server-10.10.0.tgz#0b494335140d4fd5e1452f7b57dcc9b8886720a4"
|
||||
integrity sha512-tCTqcqBT+3nebYFTHtwM877qo5xQPtVlptxKdUzMVWleWT4lFTL4oddk45qVURToci2iMbVJjd4jQU9y9/XwlQ==
|
||||
|
||||
"@types/acorn@^4.0.0":
|
||||
version "4.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/acorn/-/acorn-4.0.6.tgz#d61ca5480300ac41a7d973dd5b84d0a591154a22"
|
||||
|
@ -5185,12 +5190,7 @@ hono@3.0.0-rc.9:
|
|||
resolved "https://registry.yarnpkg.com/hono/-/hono-3.0.0-rc.9.tgz#6077bc67fce850dca99cd58452bda21ff8984da8"
|
||||
integrity sha512-gW/I51Uay6RhrDhtRN/3WTg7ALT3VRdk0NZBdGpkEOgF+TrzFwmWHDbzHUPa9MffiXSlrkFtMmJVvdKO3Iab8Q==
|
||||
|
||||
hono@^2.3.0:
|
||||
version "2.6.2"
|
||||
resolved "https://registry.yarnpkg.com/hono/-/hono-2.6.2.tgz#1e32a4b4b3bf557a8aa87e392b00b505a1ec1fdd"
|
||||
integrity sha512-Y4Uv6dPPx6u7TNoWN245tLw8jycBf97w0FJGJoEMdgdBqQEv1dqIvg5IfDhiYMkimSIt4SXxmMgiyPf2wzwFWQ==
|
||||
|
||||
hono@^2.6.1:
|
||||
hono@^2.6.1, hono@^2.7.5:
|
||||
version "2.7.5"
|
||||
resolved "https://registry.yarnpkg.com/hono/-/hono-2.7.5.tgz#2b0c39d39a057575962a7025373be4304dedca9c"
|
||||
integrity sha512-UYrhUT1Xtalh7Xw/YGXee25wlWMiVIRfr0FbAJMEMyRpX9TFZ/6JKmVdCK7ioRnhAw7PfWBasjSBhdNXQ8/okQ==
|
||||
|
@ -10806,6 +10806,11 @@ zod@3.19.1:
|
|||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.19.1.tgz#112f074a97b50bfc4772d4ad1576814bd8ac4473"
|
||||
integrity sha512-LYjZsEDhCdYET9ikFu6dVPGp2YH9DegXjdJToSzD9rO6fy4qiRYFoyEYwps88OseJlPyl2NOe2iJuhEhL7IpEA==
|
||||
|
||||
zod@^3.20.2:
|
||||
version "3.20.2"
|
||||
resolved "https://registry.yarnpkg.com/zod/-/zod-3.20.2.tgz#068606642c8f51b3333981f91c0a8ab37dfc2807"
|
||||
integrity sha512-1MzNQdAvO+54H+EaK5YpyEy0T+Ejo/7YLHS93G3RnYWh5gaotGHwGeN/ZO687qEDU2y4CdStQYXVHIgrUl5UVQ==
|
||||
|
||||
zwitch@^2.0.0:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7"
|
||||
|
|
Loading…
Reference in New Issue