关于 hono-routing
hono-routing 是面向 Hono 开发者的路由与中间件技能,提供 TypeScript 类型安全路由、请求验证、RPC 和错误处理的实践指南,适用于多种 JavaScript 运行时。
主要功能
- 01组织路由与子应用
- 02组合内置和自定义中间件
- 03扩展类型安全的上下文
- 04使用多种验证库校验请求
- 05通过 RPC 推导客户端类型
- 06配置集中式错误处理
适用场景
- 01为 Hono 应用设计路由结构
- 02验证请求参数和表单数据
- 03建立类型安全的客户端与服务端调用
- 04统一处理 HTTP 错误和未匹配路由
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ jackspace/ claudeskillz --skill hono-routing安装后在 Claude Code 中输入/hono-routing确认已加载。
附带文件README.mdSKILL.json
详细介绍
Hono 路由与中间件
状态:已准备好用于生产 ✅ 最后更新:2025-10-22 依赖项:无(与框架无关) 最新版本:[email protected]、[email protected]、[email protected]、@hono/[email protected]、@hono/[email protected]
快速入门(15 分钟)
1. 安装 Hono
npm install [email protected]
为什么选择 Hono:
- 快速:基于 Web 标准构建,可在任何 JavaScript 运行时上运行
- 轻量:约 10KB,无依赖项
- 类型安全:全面支持 TypeScript 和类型推断
- 灵活:可在 Cloudflare Workers、Deno、Bun、Node.js 和 Vercel 上运行
2. 创建基本应用
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.json({ message: 'Hello Hono!' })
})
export default app
重要:
- 使用
c.json()、c.text()、c.html()返回响应 - 返回响应(不要像 Express 那样使用
res.send()) - 为运行时导出应用(Cloudflare Workers、Deno、Bun、Node.js)
3. 添加请求验证
npm install [email protected] @hono/[email protected]
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const schema = z.object({
name: z.string(),
age: z.number(),
})
app.post('/user', zValidator('json', schema), (c) => {
const data = c.req.valid('json')
return c.json({ success: true, data })
})
验证的优势:
- 请求数据类型安全
- 自动返回错误响应
- 运行时验证,而不仅仅是 TypeScript 验证
Hono 精通指南(共 6 部分)
第 1 部分:路由模式
基本路由
import { Hono } from 'hono'
const app = new Hono()
// GET request
app.get('/posts', (c) => c.json({ posts: [] }))
// POST request
app.post('/posts', (c) => c.json({ created: true }))
// PUT request
app.put('/posts/:id', (c) => c.json({ updated: true }))
// DELETE request
app.delete('/posts/:id', (c) => c.json({ deleted: true }))
// Multiple methods
app.on(['GET', 'POST'], '/multi', (c) => c.text('GET or POST'))
// All methods
app.all('/catch-all', (c) => c.text('Any method'))
要点:
- 始终返回一个 Response(c.json、c.text、c.html 等)
- 按顺序匹配路由(第一个匹配项优先)
- 将具体路由放在通配符路由之前
路由参数
// Single parameter
app.get('/users/:id', (c) => {
const id = c.req.param('id')
return c.json({ userId: id })
})
// Multiple parameters
app.get('/posts/:postId/comments/:commentId', (c) => {
const { postId, commentId } = c.req.param()
return c.json({ postId, commentId })
})
// Optional parameters (using wildcards)
app.get('/files/*', (c) => {
const path = c.req.param('*')
return c.json({ filePath: path })
})
重要:
c.req.param('name')返回单个参数c.req.param()将所有参数作为对象返回- 参数始终是字符串(如有需要,可转换为数字)
查询参数
app.get('/search', (c) => {
// Single query param
const q = c.req.query('q')
// Multiple query params
const { page, limit } = c.req.query()
// Query param array (e.g., ?tag=js&tag=ts)
const tags = c.req.queries('tag')
return c.json({ q, page, limit, tags })
})
最佳实践:
- 对查询参数使用验证(参见第 4 部分)
- 为可选参数提供默认值
- 将查询字符串中的值解析为数字或布尔值
通配符路由
// Match any path after /api/
app.get('/api/*', (c) => {
const path = c.req.param('*')
return c.json({ catchAll: path })
})
// Named wildcard
app.get('/files/:filepath{.+}', (c) => {
const filepath = c.req.param('filepath')
return c.json({ file: filepath })
})
路由分组(子应用)
// Create sub-app
const api = new Hono()
api.get('/users', (c) => c.json({ users: [] }))
api.get('/posts', (c) => c.json({ posts: [] }))
// Mount sub-app
const app = new Hono()
app.route('/api', api)
// Result: /api/users, /api/posts
路由分组的优势:
- 组织大型应用
- 为特定路由共享中间件
- 改善代码结构和可维护性
第 2 部分:中间件组合
中间件流程
import { Hono } from 'hono'
const app = new Hono()
// Global middleware (runs for all routes)
app.use('*', async (c, next) => {
console.log(`[${c.req.method}] ${c.req.url}`)
await next() // CRITICAL: Must call next()
console.log('Response sent')
})
// Route-specific middleware
app.use('/admin/*', async (c, next) => {
// Auth check
const token = c.req.header('Authorization')
if (!token) {
return c.json({ error: 'Unauthorized' }, 401)
}
await next()
})
app.get('/admin/dashboard', (c) => {
return c.json({ message: 'Admin Dashboard' })
})
重要:
- 在中间件中始终调用
await next() - 中间件在处理程序之前运行
- 提前返回以阻止处理程序执行
- 在调用
next()后检查c.error,以处理错误
内置中间件
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { cors } from 'hono/cors'
import { prettyJSON } from 'hono/pretty-json'
import { compress } from 'hono/compress'
import { cache } from 'hono/cache'
const app = new Hono()
// Request logging
app.use('*', logger())
// CORS
app.use('/api/*', cors({
origin: 'https://example.com',
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
allowHeaders: ['Content-Type', 'Authorization'],
}))
// Pretty JSON (dev only)
app.use('*', prettyJSON())
// Compression (gzip/deflate)
app.use('*', compress())
// Cache responses
app.use(
'/static/*',
cache({
cacheName: 'my-app',
cacheControl: 'max-age=3600',
})
)
内置中间件参考:参见 references/middleware-catalog.md
中间件链式调用
// Multiple middleware in sequence
app.get(
'/protected',
authMiddleware,
rateLimitMiddleware,
(c) => {
return c.json({ data: 'Protected data' })
}
)
// Middleware factory pattern
const authMiddleware = async (c, next) => {
const token = c.req.header('Authorization')
if (!token) {
throw new HTTPException(401, { message: 'Unauthorized' })
}
// Set user in context
c.set('user', { id: 1, name: 'Alice' })
await next()
}
const rateLimitMiddleware = async (c, next) => {
// Rate limit logic
await next()
}
中间件链式调用的优势:
- 职责分离
- 可在多个路由间复用
- 执行顺序清晰
自定义中间件
// Timing middleware
const timing = async (c, next) => {
const start = Date.now()
await next()
const elapsed = Date.now() - start
c.res.headers.set('X-Response-Time', `${elapsed}ms`)
}
// Request ID middleware
const requestId = async (c, next) => {
const id = crypto.randomUUID()
c.set('requestId', id)
await next()
c.res.headers.set('X-Request-ID', id)
}
// Error logging middleware
const errorLogger = async (c, next) => {
await next()
if (c.error) {
console.error('Error:', c.error)
// Send to error tracking service
}
}
app.use('*', timing)
app.use('*', requestId)
app.use('*', errorLogger)
最佳实践:
- 让中间件职责明确(单一职责)
- 使用
c.set()在中间件之间共享数据 - 在调用
next()后检查c.error,以处理错误 - 提前返回以短路执行
第 3 部分:类型安全的上下文扩展
使用 c.set() 和 c.get()
import { Hono } from 'hono'
type Bindings = {
DATABASE_URL: string
}
type Variables = {
user: {
id: number
name: string
}
requestId: string
}
const app = new Hono<{ Bindings: Bindings; Variables: Variables }>()
// Middleware sets variables
app.use('*', async (c, next) => {
c.set('requestId', crypto.randomUUID())
await next()
})
app.use('/api/*', async (c, next) => {
c.set('user', { id: 1, name: 'Alice' })
await next()
})
// Route accesses variables
app.get('/api/profile', (c) => {
const user = c.get('user') // Type-safe!
const requestId = c.get('requestId') // Type-safe!
return c.json({ user, requestId })
})
重要:
- 定义
Variables类型,确保c.get()类型安全 - 定义
Bindings类型表示环境变量(Cloudflare Workers) - 在中间件中使用
c.set(),在处理程序中使用c.get()
自定义上下文扩展
import { Hono } from 'hono'
import type { Context } from 'hono'
type Env = {
Variables: {
logger: {
info: (message: string) => void
error: (message: string) => void
}
}
}
const app = new Hono<Env>()
// Create logger middleware
app.use('*', async (c, next) => {
const logger = {
info: (msg: string) => console.log(`[INFO] ${msg}`),
error: (msg: string) => console.error(`[ERROR] ${msg}`),
}
c.set('logger', logger)
await next()
})
app.get('/', (c) => {
const logger = c.get('logger')
logger.info('Hello from route')
return c.json({ message: 'Hello' })
})
高级模式:参见 templates/context-extension.ts
第 4 部分:请求验证
使用 Zod 验证
npm install [email protected] @hono/[email protected]
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
// Define schema
const userSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
age: z.number().int().min(18).optional(),
})
// Validate JSON body
app.post('/users', zValidator('json', userSchema), (c) => {
const data = c.req.valid('json') // Type-safe!
return c.json({ success: true, data })
})
// Validate query params
const searchSchema = z.object({
q: z.string(),
page: z.string().transform((val) => parseInt(val, 10)),
limit: z.string().transform((val) => parseInt(val, 10)).optional(),
})
app.get('/search', zValidator('query', searchSchema), (c) => {
const { q, page, limit } = c.req.valid('query')
return c.json({ q, page, limit })
})
// Validate route params
const idSchema = z.object({
id: z.string().uuid(),
})
app.get('/users/:id', zValidator('param', idSchema), (c) => {
const { id } = c.req.valid('param')
return c.json({ userId: id })
})
// Validate headers
const headerSchema = z.object({
'authorization': z.string().startsWith('Bearer '),
'content-type': z.string(),
})
app.post('/auth', zValidator('header', headerSchema), (c) => {
const headers = c.req.valid('header')
return c.json({ authenticated: true })
})
重要:
- 验证后始终使用
c.req.valid()(确保类型安全) - 验证目标:
json、query、param、header、form、cookie - 使用
z.transform()将字符串转换为数字或日期 - 验证错误会自动返回 400
自定义验证钩子
import { zValidator } from '@hono/zod-validator'
import { HTTPException } from 'hono/http-exception'
const schema = z.object({
name: z.string(),
age: z.number(),
})
// Custom error handler
app.post(
'/users',
zValidator('json', schema, (result, c) => {
if (!result.success) {
// Custom error response
return c.json(
{
error: 'Validation failed',
issues: result.error.issues,
},
400
)
}
}),
(c) => {
const data = c.req.valid('json')
return c.json({ success: true, data })
}
)
// Throw HTTPException
app.post(
'/users',
zValidator('json', schema, (result, c) => {
if (!result.success) {
throw new HTTPException(400, { cause: result.error })
}
}),
(c) => {
const data = c.req.valid('json')
return c.json({ success: true, data })
}
)
使用 Valibot 验证
npm install [email protected] @hono/[email protected]
import { vValidator } from '@hono/valibot-validator'
import * as v from 'valibot'
const schema = v.object({
name: v.string(),
age: v.number(),
})
app.post('/users', vValidator('json', schema), (c) => {
const data = c.req.valid('json')
return c.json({ success: true, data })
})
Zod 与 Valibot:参见 references/validation-libraries.md
使用 Typia 验证
npm install typia @hono/[email protected]
import { typiaValidator } from '@hono/typia-validator'
import typia from 'typia'
interface User {
name: string
age: number
}
const validate = typia.createValidate<User>()
app.post('/users', typiaValidator('json', validate), (c) => {
const data = c.req.valid('json')
return c.json({ success: true, data })
})
为什么选择 Typia:
- 验证速度最快(编译时)
- 无需在运行时定义模式
- AOT(提前)编译
使用 ArkType 验证
npm install arktype @hono/[email protected]
import { arktypeValidator } from '@hono/arktype-validator'
import { type } from 'arktype'
const schema = type({
name: 'string',
age: 'number',
})
app.post('/users', arktypeValidator('json', schema), (c) => {
const data = c.req.valid('json')
return c.json({ success: true, data })
})
比较:详细比较请参见 references/validation-libraries.md
第 5 部分:类型化路由(RPC)
为什么使用 RPC?
Hono 的 RPC 功能支持类型安全的客户端/服务端通信,无需手动定义 API 类型。客户端可直接从服务端路由推断类型。
服务端设置
// app.ts
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const app = new Hono()
const schema = z.object({
name: z.string(),
age: z.number(),
})
// Define route and export type
const route = app.post(
'/users',
zValidator('json', schema),
(c) => {
const data = c.req.valid('json')
return c.json({ success: true, data }, 201)
}
)
// Export app type for RPC client
export type AppType = typeof route
// OR export entire app
// export type AppType = typeof app
export default app
重要:
- 必须使用
const route = app.get(...)进行 RPC 类型推断 - 导出
typeof route或typeof app - 不要使用匿名路由定义
客户端设置
// client.ts
import { hc } from 'hono/client'
import type { AppType } from './app'
const client = hc<AppType>('http://localhost:8787')
// Type-safe API call
const res = await client.users.$post({
json: {
name: 'Alice',
age: 30,
},
})
// Response is typed!
const data = await res.json() // { success: boolean, data: { name: string, age: number } }
使用 RPC 的原因:
- ✅ 完整的类型推断(请求 + 响应)
- ✅ 无需手动定义类型
- ✅ 编译时错误检查
- ✅ 在 IDE 中自动补全
使用多个路由的 RPC
// Server
const app = new Hono()
const getUsers = app.get('/users', (c) => {
return c.json({ users: [] })
})
const createUser = app.post(
'/users',
zValidator('json', userSchema),
(c) => {
const data = c.req.valid('json')
return c.json({ success: true, data }, 201)
}
)
const getUser = app.get('/users/:id', (c) => {
const id = c.req.param('id')
return c.json({ id, name: 'Alice' })
})
// Export combined type
export type AppType = typeof getUsers | typeof createUser | typeof getUser
// Client
const client = hc<AppType>('http://localhost:8787')
// GET /users
const usersRes = await client.users.$get()
// POST /users
const createRes = await client.users.$post({
json: { name: 'Alice', age: 30 },
})
// GET /users/:id
const userRes = await client.users[':id'].$get({
param: { id: '123' },
})
RPC 性能优化
问题:包含许多路由的大型应用会导致类型推断变慢
解决方案:导出特定的路由组,而不是整个应用
// ❌ Slow: Export entire app
export type AppType = typeof app
// ✅ Fast: Export specific routes
const userRoutes = app.get('/users', ...).post('/users', ...)
export type UserRoutes = typeof userRoutes
const postRoutes = app.get('/posts', ...).post('/posts', ...)
export type PostRoutes = typeof postRoutes
// Client imports specific routes
import type { UserRoutes } from './app'
const userClient = hc<UserRoutes>('http://localhost:8787')
深入了解:请参阅 references/rpc-guide.md
第 6 部分:错误处理
HTTPException
import { Hono } from 'hono'
import { HTTPException } from 'hono/http-exception'
const app = new Hono()
app.get('/users/:id', (c) => {
const id = c.req.param('id')
// Throw HTTPException for client errors
if (!id) {
throw new HTTPException(400, { message: 'ID is required' })
}
// With custom response
if (id === 'invalid') {
const res = new Response('Custom error body', { status: 400 })
throw new HTTPException(400, { res })
}
return c.json({ id })
})
重要:
- 对预期错误(400、401、403、404)使用 HTTPException
- 不要对意外错误(500)使用它——改用
onError - HTTPException 会立即停止执行
全局错误处理程序(onError)
import { Hono } from 'hono'
import { HTTPException } from 'hono/http-exception'
const app = new Hono()
// Custom error handler
app.onError((err, c) => {
// Handle HTTPException
if (err instanceof HTTPException) {
return err.getResponse()
}
// Handle unexpected errors
console.error('Unexpected error:', err)
return c.json(
{
error: 'Internal Server Error',
message: err.message,
},
500
)
})
app.get('/error', (c) => {
throw new Error('Something went wrong!')
})
使用 onError 的原因:
- 集中处理错误
- 确保错误响应一致
- 记录和跟踪错误
中间件错误检查
app.use('*', async (c, next) => {
await next()
// Check for errors after handler
if (c.error) {
console.error('Error in route:', c.error)
// Send to error tracking service
}
})
未找到处理程序
app.notFound((c) => {
return c.json({ error: 'Not Found' }, 404)
})
错误处理最佳实践
import { Hono } from 'hono'
import { HTTPException } from 'hono/http-exception'
const app = new Hono()
// Validation errors
app.post('/users', zValidator('json', schema), (c) => {
// zValidator automatically returns 400 on validation failure
const data = c.req.valid('json')
return c.json({ data })
})
// Authorization errors
app.use('/admin/*', async (c, next) => {
const token = c.req.header('Authorization')
if (!token) {
throw new HTTPException(401, { message: 'Unauthorized' })
}
await next()
})
// Not found errors
app.get('/users/:id', async (c) => {
const id = c.req.param('id')
const user = await db.getUser(id)
if (!user) {
throw new HTTPException(404, { message: 'User not found' })
}
return c.json({ user })
})
// Server errors
app.get('/data', async (c) => {
try {
const data = await fetchExternalAPI()
return c.json({ data })
} catch (error) {
// Let onError handle it
throw error
}
})
// Global error handler
app.onError((err, c) => {
if (err instanceof HTTPException) {
return err.getResponse()
}
console.error('Unexpected error:', err)
return c.json({ error: 'Internal Server Error' }, 500)
})
// 404 handler
app.notFound((c) => {
return c.json({ error: 'Not Found' }, 404)
})
关键规则
始终执行
✅ 在中间件中调用 await next() —— 中间件链执行所必需
✅ 在处理程序中返回 Response —— 使用 c.json()、c.text()、c.html()
✅ 验证后使用 c.req.valid() —— 获取类型安全的已验证数据
✅ 为 RPC 导出路由类型 —— export type AppType = typeof route
✅ 对客户端错误抛出 HTTPException —— 400、401、403、404 错误
✅ 使用 onError 进行全局错误处理 —— 集中处理错误响应
✅ 为 c.set/c.get 定义 Variables 类型 —— 确保上下文变量类型安全
✅ 使用 const route = app.get(...) —— RPC 类型推断所必需
绝不执行
❌ 在中间件中忘记 await next() —— 会中断中间件链
❌ 像 Express 一样使用 res.send() —— 与 Hono 不兼容
❌ 未经验证就访问请求数据 —— 使用验证器确保类型安全
❌ 为大型 RPC 导出整个应用 —— 类型推断会变慢,应导出特定路由
❌ 直接使用 plain throw new Error() —— 改用 HTTPException
❌ 省略 onError 处理程序 —— 会导致错误响应不一致
❌ 不定义 Variables 类型就使用 c.set/c.get —— 会失去类型安全
已知问题预防
此技能可预防 8 个已记录的问题:
问题 #1:RPC 类型推断缓慢
错误:路由过多时 IDE 运行缓慢
来源:hono/docs/guides/rpc
原因:使用包含许多路由的 typeof app 会导致类型实例化复杂
预防方法:导出特定的路由组,而不是整个应用
// ❌ Slow
export type AppType = typeof app
// ✅ Fast
const userRoutes = app.get(...).post(...)
export type UserRoutes = typeof userRoutes
问题 #2:RPC 中间件响应类型未推断
错误:RPC 客户端无法推断中间件响应 来源:honojs/hono#2719 原因:默认情况下,RPC 模式不会推断中间件响应 预防方法:导出包含中间件的特定路由类型
const route = app.get(
'/data',
myMiddleware,
(c) => c.json({ data: 'value' })
)
export type AppType = typeof route
问题 #3:验证钩子容易混淆
错误:不同的验证器库采用不同的钩子模式 来源:Context7 研究 原因:每种验证器(@hono/zod-validator、@hono/valibot-validator 等)的 API 都略有不同 预防方法:此技能为所有验证器提供一致的模式
问题 #4:误用 HTTPException
错误:抛出普通 Error,而不是 HTTPException
来源:官方文档
原因:熟悉 Express 的开发者会使用 throw new Error()
预防方法:客户端错误(400-499)始终使用 HTTPException
// ❌ Wrong
throw new Error('Unauthorized')
// ✅ Correct
throw new HTTPException(401, { message: 'Unauthorized' })
问题 #5:上下文类型安全丢失
错误:使用 c.set() 和 c.get() 时无法推断类型
来源:官方文档
原因:未在 Hono 泛型中定义 Variables 类型
预防方法:始终定义 Variables 类型
type Variables = {
user: { id: number; name: string }
}
const app = new Hono<{ Variables: Variables }>()
问题 #6:中间件之后缺少错误检查
错误:处理程序中的错误未被捕获
来源:官方文档
原因:在 await next() 之后未检查 c.error
预防措施:在中间件中检查 c.error
app.use('*', async (c, next) => {
await next()
if (c.error) {
console.error('Error:', c.error)
}
})
问题 #7:未经验证直接访问请求
错误:未经验证就访问 c.req.param() 或 c.req.query()
来源:最佳实践
原因:开发者为了速度跳过验证
预防措施:始终使用验证器和 c.req.valid()
// ❌ Wrong
const id = c.req.param('id') // string, no validation
// ✅ Correct
app.get('/users/:id', zValidator('param', idSchema), (c) => {
const { id } = c.req.valid('param') // validated UUID
})
问题 #8:中间件顺序错误
错误:中间件执行顺序错误
来源:官方文档
原因:误解了中间件链的执行方式
预防措施:牢记中间件自上而下运行,await next() 会运行处理程序,然后再自下而上返回
app.use('*', async (c, next) => {
console.log('1: Before handler')
await next()
console.log('4: After handler')
})
app.use('*', async (c, next) => {
console.log('2: Before handler')
await next()
console.log('3: After handler')
})
app.get('/', (c) => {
console.log('Handler')
return c.json({})
})
// Output: 1, 2, Handler, 3, 4
配置文件参考
package.json(完整示例)
{
"name": "hono-app",
"version": "1.0.0",
"type": "module",
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc",
"start": "node dist/index.js"
},
"dependencies": {
"hono": "^4.10.2"
},
"devDependencies": {
"typescript": "^5.9.0",
"tsx": "^4.19.0",
"@types/node": "^22.10.0"
}
}
使用验证的 package.json(Zod)
{
"dependencies": {
"hono": "^4.10.2",
"zod": "^4.1.12",
"@hono/zod-validator": "^0.7.4"
}
}
使用验证的 package.json(Valibot)
{
"dependencies": {
"hono": "^4.10.2",
"valibot": "^1.1.0",
"@hono/valibot-validator": "^0.5.3"
}
}
包含所有验证器的 package.json
{
"dependencies": {
"hono": "^4.10.2",
"zod": "^4.1.12",
"valibot": "^1.1.0",
"@hono/zod-validator": "^0.7.4",
"@hono/valibot-validator": "^0.5.3",
"@hono/typia-validator": "^0.1.2",
"@hono/arktype-validator": "^2.0.1"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "ES2022",
"module": "ES2022",
"lib": ["ES2022"],
"moduleResolution": "bundler",
"resolveJsonModule": true,
"allowJs": true,
"checkJs": false,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"outDir": "./dist"
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}
文件模板
所有模板均位于 templates/ 目录中:
- routing-patterns.ts - 路由参数、查询参数、通配符、分组
- middleware-composition.ts - 中间件链、内置中间件
- validation-zod.ts - 使用自定义钩子的 Zod 验证
- validation-valibot.ts - Valibot 验证
- rpc-pattern.ts - 类型安全的 RPC 客户端/服务端
- error-handling.ts - HTTPException、onError、自定义错误
- context-extension.ts - c.set/c.get、自定义上下文类型
- package.json - 所有依赖项
将这些文件复制到你的项目中,并根据需要进行自定义。
参考文档
如需深入了解,请参阅:
- middleware-catalog.md - 完整的 Hono 内置中间件参考
- validation-libraries.md - Zod、Valibot、Typia 和 ArkType 对比
- rpc-guide.md - 深入了解 RPC 模式、性能优化
- top-errors.md - 常见 Hono 错误及解决方案
官方文档
- Hono:https://hono.dev
- Hono 路由:https://hono.dev/docs/api/routing
- Hono 中间件:https://hono.dev/docs/guides/middleware
- Hono 验证:https://hono.dev/docs/guides/validation
- Hono RPC:https://hono.dev/docs/guides/rpc
- Hono 上下文:https://hono.dev/docs/api/context
- Context7 库 ID:
/llmstxt/hono_dev_llms-full_txt
依赖项(最新验证日期:2025-10-22)
{
"dependencies": {
"hono": "^4.10.2"
},
"optionalDependencies": {
"zod": "^4.1.12",
"valibot": "^1.1.0",
"@hono/zod-validator": "^0.7.4",
"@hono/valibot-validator": "^0.5.3",
"@hono/typia-validator": "^0.1.2",
"@hono/arktype-validator": "^2.0.1"
},
"devDependencies": {
"typescript": "^5.9.0"
}
}
生产环境示例
此技能已在多种运行时环境中验证:
- Cloudflare Workers:路由、中间件、RPC 模式
- Deno:已测试所有验证库
- Bun:已完成性能基准测试
- Node.js:完整测试套件通过
此技能中的所有模式均已在生产环境中验证。
有疑问?遇到问题?
- 首先查看
references/top-errors.md - 核实设置流程中的所有步骤
- 确保在中间件中调用
await next() - 确保 RPC 路由使用
const route = app.get(...)模式 - 查看官方文档:https://hono.dev