RPC 客户端
Hono 的 RPC 功能可以把服务端路由类型共享给客户端。它不是传统意义上的独立 RPC 协议,而是基于 Hono 路由类型和客户端辅助函数生成类型安全的调用方式。
服务端导出 AppType
先在服务端写路由:
import { Hono } from 'hono'
import { z } from 'zod'
import { zValidator } from '@hono/zod-validator'
const app = new Hono()
const route = app.post(
'/posts',
zValidator(
'json',
z.object({
title: z.string().min(1),
body: z.string().min(1),
}),
),
async (c) => {
const input = c.req.valid('json')
return c.json({
id: crypto.randomUUID(),
...input,
})
},
)
export type AppType = typeof route
export default app
关键点是导出 typeof route 或包含路由的应用类型。
客户端使用 hc
客户端安装 hono 后使用 hc:
import { hc } from 'hono/client'
import type { AppType } from '../server'
const client = hc<AppType>('http://localhost:3000')
const res = await client.posts.$post({
json: {
title: 'Hono RPC',
body: '类型可以从服务端路由推导',
},
})
if (res.ok) {
const post = await res.json()
console.log(post.id)
}
当验证器声明了输入结构,客户端调用时也能获得对应类型提示。
Monorepo 中的结构
一个常见结构:
apps/
├─ api/
│ └─ src/index.ts
└─ web/
└─ src/api.ts
packages/
└─ shared/
客户端应该只导入服务端导出的类型,不要导入会执行服务端代码的运行时对象。可以单独放一个 app-type.ts:
// apps/api/src/app-type.ts
import type { app } from './app'
export type AppType = typeof app
tsconfig 要点
官方 RPC 文档建议在客户端和服务端的 tsconfig.json 中开启严格模式:
{
"compilerOptions": {
"strict": true
}
}
如果类型没有正确推导,先检查:
- 客户端导入的是
type,不是运行时代码。 - 服务端导出的类型覆盖了实际路由。
- 客户端和服务端使用的 Hono 版本一致。
strict没有关掉。
适用场景
Hono RPC 适合小到中型 TypeScript 全栈项目,尤其是同一个仓库里同时维护 API 和前端客户端的场景。
如果你的客户端很多、语言不统一,或者需要公开长期稳定协议,更适合同时提供 OpenAPI 文档或手写 SDK。
相关内容
- Hono 是什么 介绍 Hono 的定位、核心特点、Web Standards 思路、多运行时能力,以及它与传统 Node.js Web 框架的差异。
- 安装和 Hello World 学习使用 create-hono 创建 Hono 项目,分别了解通用模板和 Node.js 模板的 Hello World 写法。
- 运行时选择 对比 Hono 在 Node.js、Cloudflare Workers、Bun、Deno 等运行时中的入口写法、部署方式和适用场景。
- 路由基础 学习 Hono 的 GET、POST、动态参数、通配符、路由分组和模块化路由写法。
- Context 详解 介绍 Hono Context 的 req、json、text、html、redirect、header、status、set、get 等常用 API。
- 中间件机制 学习 Hono 中间件的执行顺序、自定义中间件写法、路径匹配、next 调用和常见使用场景。