hono-routing
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHono Routing & Middleware
Hono路由与中间件
Status: Production Ready ✅
Last Updated: 2025-10-22
Dependencies: None (framework-agnostic)
Latest Versions: hono@4.10.2, zod@4.1.12, valibot@1.1.0, @hono/zod-validator@0.7.4, @hono/valibot-validator@0.5.3
状态:生产就绪 ✅
最后更新:2025-10-22
依赖:无(与框架无关)
最新版本:hono@4.10.2, zod@4.1.12, valibot@1.1.0, @hono/zod-validator@0.7.4, @hono/valibot-validator@0.5.3
Quick Start (15 Minutes)
快速开始(15分钟)
1. Install Hono
1. 安装Hono
bash
npm install hono@4.10.2Why Hono:
- Fast: Built on Web Standards, runs on any JavaScript runtime
- Lightweight: ~10KB, no dependencies
- Type-safe: Full TypeScript support with type inference
- Flexible: Works on Cloudflare Workers, Deno, Bun, Node.js, Vercel
bash
npm install hono@4.10.2选择Hono的理由:
- 快速:基于Web标准构建,可在任意JavaScript运行时运行
- 轻量:约10KB,无额外依赖
- 类型安全:全面支持TypeScript类型推断
- 灵活:可在Cloudflare Workers、Deno、Bun、Node.js、Vercel上运行
2. Create Basic App
2. 创建基础应用
typescript
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => {
return c.json({ message: 'Hello Hono!' })
})
export default appCRITICAL:
- Use ,
c.json(),c.text()for responsesc.html() - Return the response (don't use like Express)
res.send() - Export app for runtime (Cloudflare Workers, Deno, Bun, Node.js)
typescript
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() - 导出app以适配运行时(Cloudflare Workers、Deno、Bun、Node.js)
3. Add Request Validation
3. 添加请求验证
bash
npm install zod@4.1.12 @hono/zod-validator@0.7.4typescript
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 })
})Why Validation:
- Type-safe request data
- Automatic error responses
- Runtime validation, not just TypeScript
bash
npm install zod@4.1.12 @hono/zod-validator@0.7.4typescript
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层面的类型检查,还包含运行时验证
The 6-Part Hono Mastery Guide
Hono精通指南(6部分)
Part 1: Routing Patterns
第1部分:路由模式
Basic Routes
基础路由
typescript
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'))Key Points:
- Always return a Response (c.json, c.text, c.html, etc.)
- Routes are matched in order (first match wins)
- Use specific routes before wildcard routes
typescript
import { Hono } from 'hono'
const app = new Hono()
// GET请求
app.get('/posts', (c) => c.json({ posts: [] }))
// POST请求
app.post('/posts', (c) => c.json({ created: true }))
// PUT请求
app.put('/posts/:id', (c) => c.json({ updated: true }))
// DELETE请求
app.delete('/posts/:id', (c) => c.json({ deleted: true }))
// 多方法支持
app.on(['GET', 'POST'], '/multi', (c) => c.text('GET或POST请求'))
// 所有方法
app.all('/catch-all', (c) => c.text('任意请求方法'))关键点:
- 必须返回Response对象(c.json、c.text、c.html等)
- 路由按定义顺序匹配(先匹配的路由生效)
- 通配符路由应放在具体路由之后
Route Parameters
路由参数
typescript
// 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 })
})CRITICAL:
- returns single parameter
c.req.param('name') - returns all parameters as object
c.req.param() - Parameters are always strings (cast to number if needed)
typescript
// 单个参数
app.get('/users/:id', (c) => {
const id = c.req.param('id')
return c.json({ userId: id })
})
// 多个参数
app.get('/posts/:postId/comments/:commentId', (c) => {
const { postId, commentId } = c.req.param()
return c.json({ postId, commentId })
})
// 可选参数(使用通配符)
app.get('/files/*', (c) => {
const path = c.req.param('*')
return c.json({ filePath: path })
})关键注意事项:
- 返回单个参数
c.req.param('name') - 返回所有参数组成的对象
c.req.param() - 参数始终为字符串类型(如需数字需自行转换)
Query Parameters
查询参数
typescript
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 })
})Best Practice:
- Use validation for query params (see Part 4)
- Provide defaults for optional params
- Parse numbers/booleans from query strings
typescript
app.get('/search', (c) => {
// 单个查询参数
const q = c.req.query('q')
// 多个查询参数
const { page, limit } = c.req.query()
// 查询参数数组(例如:?tag=js&tag=ts)
const tags = c.req.queries('tag')
return c.json({ q, page, limit, tags })
})最佳实践:
- 对查询参数使用验证(见第4部分)
- 为可选参数提供默认值
- 将查询字符串转换为数字/布尔值
Wildcard Routes
通配符路由
typescript
// 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 })
})typescript
// 匹配/api/后的任意路径
app.get('/api/*', (c) => {
const path = c.req.param('*')
return c.json({ catchAll: path })
})
// 命名通配符
app.get('/files/:filepath{.+}', (c) => {
const filepath = c.req.param('filepath')
return c.json({ file: filepath })
})Route Grouping (Sub-apps)
路由分组(子应用)
typescript
// 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/postsWhy Group Routes:
- Organize large applications
- Share middleware for specific routes
- Better code structure and maintainability
typescript
// 创建子应用
const api = new Hono()
api.get('/users', (c) => c.json({ users: [] }))
api.get('/posts', (c) => c.json({ posts: [] }))
// 挂载子应用
const app = new Hono()
app.route('/api', api)
// 结果:/api/users, /api/posts路由分组的优势:
- 组织大型应用的路由结构
- 为特定路由共享中间件
- 提升代码结构的清晰度和可维护性
Part 2: Middleware Composition
第2部分:中间件组合
Middleware Flow
中间件流程
typescript
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' })
})CRITICAL:
- Always call in middleware
await next() - Middleware runs BEFORE the handler
- Return early to prevent handler execution
- Check AFTER
c.errorfor error handlingnext()
typescript
import { Hono } from 'hono'
const app = new Hono()
// 全局中间件(对所有路由生效)
app.use('*', async (c, next) => {
console.log(`[${c.req.method}] ${c.req.url}`)
await next() // 关键:必须调用next()
console.log('响应已发送')
})
// 路由专属中间件
app.use('/admin/*', async (c, next) => {
// 权限校验
const token = c.req.header('Authorization')
if (!token) {
return c.json({ error: '未授权' }, 401)
}
await next()
})
app.get('/admin/dashboard', (c) => {
return c.json({ message: '管理员控制台' })
})关键注意事项:
- 中间件中必须调用
await next() - 中间件在处理器之前执行
- 可提前返回以阻止处理器执行
- 调用后可通过
next()处理错误c.error
Built-in Middleware
内置中间件
typescript
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',
})
)Built-in Middleware Reference: See
references/middleware-catalog.mdtypescript
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()
// 请求日志
app.use('*', logger())
// CORS配置
app.use('/api/*', cors({
origin: 'https://example.com',
allowMethods: ['GET', 'POST', 'PUT', 'DELETE'],
allowHeaders: ['Content-Type', 'Authorization'],
}))
// 美化JSON输出(仅开发环境使用)
app.use('*', prettyJSON())
// 压缩响应(gzip/deflate)
app.use('*', compress())
// 响应缓存
app.use(
'/static/*',
cache({
cacheName: 'my-app',
cacheControl: 'max-age=3600',
})
)内置中间件参考:详见
references/middleware-catalog.mdMiddleware Chaining
中间件链式调用
typescript
// 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()
}Why Chain Middleware:
- Separation of concerns
- Reusable across routes
- Clear execution order
typescript
// 按顺序调用多个中间件
app.get(
'/protected',
authMiddleware,
rateLimitMiddleware,
(c) => {
return c.json({ data: '受保护数据' })
}
)
// 中间件工厂模式
const authMiddleware = async (c, next) => {
const token = c.req.header('Authorization')
if (!token) {
throw new HTTPException(401, { message: '未授权' })
}
// 将用户信息存入上下文
c.set('user', { id: 1, name: 'Alice' })
await next()
}
const rateLimitMiddleware = async (c, next) => {
// 限流逻辑
await next()
}链式调用中间件的优势:
- 关注点分离
- 可在多个路由间复用
- 执行顺序清晰
Custom Middleware
自定义中间件
typescript
// 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)Best Practices:
- Keep middleware focused (single responsibility)
- Use to share data between middleware
c.set() - Check AFTER
c.errorfor error handlingnext() - Return early to short-circuit execution
typescript
// 响应计时中间件
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`)
}
// 请求ID中间件
const requestId = async (c, next) => {
const id = crypto.randomUUID()
c.set('requestId', id)
await next()
c.res.headers.set('X-Request-ID', id)
}
// 错误日志中间件
const errorLogger = async (c, next) => {
await next()
if (c.error) {
console.error('错误信息:', c.error)
// 发送到错误追踪服务
}
}
app.use('*', timing)
app.use('*', requestId)
app.use('*', errorLogger)最佳实践:
- 中间件保持单一职责
- 使用在中间件间共享数据
c.set() - 调用后检查
next()处理错误c.error - 可提前返回以中断执行链
Part 3: Type-Safe Context Extension
第3部分:类型安全的上下文扩展
Using c.set() and c.get()
使用c.set()和c.get()
typescript
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 })
})CRITICAL:
- Define type for type-safe
Variablesc.get() - Define type for environment variables (Cloudflare Workers)
Bindings - in middleware,
c.set()in handlersc.get()
typescript
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 }>()
// 中间件设置变量
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()
})
// 路由获取变量
app.get('/api/profile', (c) => {
const user = c.get('user') // 类型安全!
const requestId = c.get('requestId') // 类型安全!
return c.json({ user, requestId })
})关键注意事项:
- 定义类型以实现
Variables的类型安全c.get() - 定义类型以适配环境变量(Cloudflare Workers)
Bindings - 在中间件中使用,在处理器中使用
c.set()c.get()
Custom Context Extension
自定义上下文扩展
typescript
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' })
})Advanced Pattern: See
templates/context-extension.tstypescript
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>()
// 创建日志中间件
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('来自路由的消息')
return c.json({ message: 'Hello' })
})高级模式:详见
templates/context-extension.tsPart 4: Request Validation
第4部分:请求验证
Validation with Zod
使用Zod进行验证
bash
npm install zod@4.1.12 @hono/zod-validator@0.7.4typescript
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 })
})CRITICAL:
- Always use after validation (type-safe)
c.req.valid() - Validation targets: ,
json,query,param,header,formcookie - Use to convert strings to numbers/dates
z.transform() - Validation errors return 400 automatically
bash
npm install zod@4.1.12 @hono/zod-validator@0.7.4typescript
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
// 定义校验规则
const userSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
age: z.number().int().min(18).optional(),
})
// 验证JSON请求体
app.post('/users', zValidator('json', userSchema), (c) => {
const data = c.req.valid('json') // 类型安全!
return c.json({ success: true, data })
})
// 验证查询参数
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 })
})
// 验证路由参数
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 })
})
// 验证请求头
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、formcookie - 使用将字符串转换为数字/日期
z.transform() - 验证失败时自动返回400错误
Custom Validation Hooks
自定义验证钩子
typescript
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 })
}
)typescript
import { zValidator } from '@hono/zod-validator'
import { HTTPException } from 'hono/http-exception'
const schema = z.object({
name: z.string(),
age: z.number(),
})
// 自定义错误处理器
app.post(
'/users',
zValidator('json', schema, (result, c) => {
if (!result.success) {
// 自定义错误响应
return c.json(
{
error: '验证失败',
issues: result.error.issues,
},
400
)
}
}),
(c) => {
const data = c.req.valid('json')
return c.json({ success: true, data })
}
)
// 抛出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 })
}
)Validation with Valibot
使用Valibot进行验证
bash
npm install valibot@1.1.0 @hono/valibot-validator@0.5.3typescript
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 vs Valibot: See
references/validation-libraries.mdbash
npm install valibot@1.1.0 @hono/valibot-validator@0.5.3typescript
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 vs Valibot:详见
references/validation-libraries.mdValidation with Typia
使用Typia进行验证
bash
npm install typia @hono/typia-validator@0.1.2typescript
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 })
})Why Typia:
- Fastest validation (compile-time)
- No runtime schema definition
- AOT (Ahead-of-Time) compilation
bash
npm install typia @hono/typia-validator@0.1.2typescript
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(提前编译)
Validation with ArkType
使用ArkType进行验证
bash
npm install arktype @hono/arktype-validator@2.0.1typescript
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 })
})Comparison: See for detailed comparison
references/validation-libraries.mdbash
npm install arktype @hono/arktype-validator@2.0.1typescript
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.mdPart 5: Typed Routes (RPC)
第5部分:类型化路由(RPC)
Why RPC?
为什么选择RPC?
Hono's RPC feature allows type-safe client/server communication without manual API type definitions. The client infers types directly from the server routes.
Hono的RPC功能支持类型安全的客户端/服务端通信,无需手动定义API类型。客户端可直接从服务端路由推断类型。
Server-Side Setup
服务端配置
typescript
// 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 appCRITICAL:
- Must use for RPC type inference
const route = app.get(...) - Export or
typeof routetypeof app - Don't use anonymous route definitions
typescript
// 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(),
})
// 定义路由并导出类型
const route = app.post(
'/users',
zValidator('json', schema),
(c) => {
const data = c.req.valid('json')
return c.json({ success: true, data }, 201)
}
)
// 导出供RPC客户端使用的应用类型
export type AppType = typeof route
// 或者导出整个应用
// export type AppType = typeof app
export default app关键注意事项:
- 必须使用的形式才能支持RPC类型推断
const route = app.get(...) - 导出或
typeof routetypeof app - 不要使用匿名路由定义
Client-Side Setup
客户端配置
typescript
// 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 } }Why RPC:
- ✅ Full type inference (request + response)
- ✅ No manual type definitions
- ✅ Compile-time error checking
- ✅ Auto-complete in IDE
typescript
// client.ts
import { hc } from 'hono/client'
import type { AppType } from './app'
const client = hc<AppType>('http://localhost:8787')
// 类型安全的API调用
const res = await client.users.$post({
json: {
name: 'Alice',
age: 30,
},
})
// 响应类型已推断!
const data = await res.json() // { success: boolean, data: { name: string, age: number } }RPC的优势:
- ✅ 完整的类型推断(请求+响应)
- ✅ 无需手动定义类型
- ✅ 编译时错误检查
- ✅ IDE自动补全
RPC with Multiple Routes
多路由RPC配置
typescript
// 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' },
})typescript
// 服务端
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 type AppType = typeof getUsers | typeof createUser | typeof getUser
// 客户端
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 Performance Optimization
RPC性能优化
Problem: Large apps with many routes cause slow type inference
Solution: Export specific route groups instead of entire app
typescript
// ❌ 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')Deep Dive: See
references/rpc-guide.md问题:包含大量路由的大型应用会导致类型推断速度变慢
解决方案:导出特定的路由组而非整个应用
typescript
// ❌ 速度慢:导出整个应用
export type AppType = typeof app
// ✅ 速度快:导出特定路由组
const userRoutes = app.get('/users', ...).post('/users', ...)
export type UserRoutes = typeof userRoutes
const postRoutes = app.get('/posts', ...).post('/posts', ...)
export type PostRoutes = typeof postRoutes
// 客户端导入特定路由组
import type { UserRoutes } from './app'
const userClient = hc<UserRoutes>('http://localhost:8787')深入探讨:详见
references/rpc-guide.mdPart 6: Error Handling
第6部分:错误处理
HTTPException
HTTPException
typescript
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 })
})CRITICAL:
- Use HTTPException for expected errors (400, 401, 403, 404)
- Don't use for unexpected errors (500) - use instead
onError - HTTPException stops execution immediately
typescript
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')
// 针对客户端错误抛出HTTPException
if (!id) {
throw new HTTPException(400, { message: 'ID是必填项' })
}
// 自定义响应内容
if (id === 'invalid') {
const res = new Response('自定义错误内容', { status: 400 })
throw new HTTPException(400, { res })
}
return c.json({ id })
})关键注意事项:
- 针对预期错误使用HTTPException(400、401、403、404)
- 不要针对意外错误使用(500)- 应使用处理
onError - HTTPException会立即终止执行
Global Error Handler (onError)
全局错误处理器(onError)
typescript
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!')
})Why onError:
- Centralized error handling
- Consistent error responses
- Error logging and tracking
typescript
import { Hono } from 'hono'
import { HTTPException } from 'hono/http-exception'
const app = new Hono()
// 自定义错误处理器
app.onError((err, c) => {
// 处理HTTPException
if (err instanceof HTTPException) {
return err.getResponse()
}
// 处理意外错误
console.error('意外错误:', err)
return c.json(
{
error: '内部服务器错误',
message: err.message,
},
500
)
})
app.get('/error', (c) => {
throw new Error('发生了错误!')
})onError的作用:
- 集中处理所有错误
- 确保错误响应格式一致
- 便于错误日志记录和追踪
Middleware Error Checking
中间件错误检查
typescript
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
}
})typescript
app.use('*', async (c, next) => {
await next()
// 处理器执行后检查错误
if (c.error) {
console.error('路由错误:', c.error)
// 发送到错误追踪服务
}
})Not Found Handler
404未找到处理器
typescript
app.notFound((c) => {
return c.json({ error: 'Not Found' }, 404)
})typescript
app.notFound((c) => {
return c.json({ error: '未找到资源' }, 404)
})Error Handling Best Practices
错误处理最佳实践
typescript
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)
})typescript
import { Hono } from 'hono'
import { HTTPException } from 'hono/http-exception'
const app = new Hono()
// 验证错误
app.post('/users', zValidator('json', schema), (c) => {
// zValidator会在验证失败时自动返回400错误
const data = c.req.valid('json')
return c.json({ data })
})
// 授权错误
app.use('/admin/*', async (c, next) => {
const token = c.req.header('Authorization')
if (!token) {
throw new HTTPException(401, { message: '未授权' })
}
await next()
})
// 资源未找到错误
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: '用户不存在' })
}
return c.json({ user })
})
// 服务器错误
app.get('/data', async (c) => {
try {
const data = await fetchExternalAPI()
return c.json({ data })
} catch (error) {
// 交给onError处理
throw error
}
})
// 全局错误处理器
app.onError((err, c) => {
if (err instanceof HTTPException) {
return err.getResponse()
}
console.error('意外错误:', err)
return c.json({ error: '内部服务器错误' }, 500)
})
// 404处理器
app.notFound((c) => {
return c.json({ error: '未找到资源' }, 404)
})Critical Rules
关键规则
Always Do
必须遵守
✅ Call in middleware - Required for middleware chain execution
✅ Return Response from handlers - Use , ,
✅ Use after validation - Type-safe validated data
✅ Export route types for RPC -
✅ Throw HTTPException for client errors - 400, 401, 403, 404 errors
✅ Use for global error handling - Centralized error responses
✅ Define Variables type for c.set/c.get - Type-safe context variables
✅ Use const route = app.get(...) - Required for RPC type inference
await next()c.json()c.text()c.html()c.req.valid()export type AppType = typeof routeonError✅ 中间件中调用 - 中间件链执行的必要条件
✅ 处理器返回Response对象 - 使用、、
✅ 验证后使用 - 获取类型安全的验证后数据
✅ 为RPC导出路由类型 -
✅ 客户端错误抛出HTTPException - 400、401、403、404等错误
✅ 使用进行全局错误处理 - 集中处理错误响应
✅ 为c.set/c.get定义Variables类型 - 确保上下文变量类型安全
✅ 使用const route = app.get(...)定义路由 - 支持RPC类型推断的必要条件
await next()c.json()c.text()c.html()c.req.valid()export type AppType = typeof routeonErrorNever Do
禁止操作
❌ Forget in middleware - Breaks middleware chain
❌ Use like Express - Not compatible with Hono
❌ Access request data without validation - Use validators for type safety
❌ Export entire app for large RPC - Slow type inference, export specific routes
❌ Use plain throw new Error() - Use HTTPException instead
❌ Skip onError handler - Leads to inconsistent error responses
❌ Use c.set/c.get without Variables type - Loses type safety
await next()res.send()❌ 中间件中忘记 - 会中断中间件链
❌ 像Express那样使用 - 与Hono不兼容
❌ 未验证直接访问请求数据 - 使用验证器确保类型安全
❌ 大型应用导出整个应用用于RPC - 类型推断速度慢,应导出特定路由组
❌ 直接抛出new Error() - 应使用HTTPException替代
❌ 跳过onError处理器 - 会导致错误响应格式不一致
❌ 未定义Variables类型就使用c.set/c.get - 丢失类型安全
await next()res.send()Known Issues Prevention
已知问题预防
This skill prevents 8 documented issues:
本技能可预防8个已记录的问题:
Issue #1: RPC Type Inference Slow
问题1:RPC类型推断速度慢
Error: IDE becomes slow with many routes
Source: hono/docs/guides/rpc
Why It Happens: Complex type instantiation from with many routes
Prevention: Export specific route groups instead of entire app
typeof apptypescript
// ❌ Slow
export type AppType = typeof app
// ✅ Fast
const userRoutes = app.get(...).post(...)
export type UserRoutes = typeof userRoutes错误现象:包含大量路由时IDE运行缓慢
来源:hono/docs/guides/rpc
原因:会生成复杂的类型实例,导致类型推断缓慢
解决方法:导出特定的路由组而非整个应用
typeof apptypescript
// ❌ 速度慢
export type AppType = typeof app
// ✅ 速度快
const userRoutes = app.get(...).post(...)
export type UserRoutes = typeof userRoutesIssue #2: Middleware Response Not Typed in RPC
问题2:RPC客户端未推断中间件响应
Error: Middleware responses not inferred by RPC client
Source: honojs/hono#2719
Why It Happens: RPC mode doesn't infer middleware responses by default
Prevention: Export specific route types that include middleware
typescript
const route = app.get(
'/data',
myMiddleware,
(c) => c.json({ data: 'value' })
)
export type AppType = typeof route错误现象:中间件的响应未被RPC客户端推断
来源:honojs/hono#2719
原因:RPC模式默认不会推断中间件的响应
解决方法:导出包含中间件的特定路由类型
typescript
const route = app.get(
'/data',
myMiddleware,
(c) => c.json({ data: 'value' })
)
export type AppType = typeof routeIssue #3: Validation Hook Confusion
问题3:验证钩子混淆
Error: Different validator libraries have different hook patterns
Source: Context7 research
Why It Happens: Each validator (@hono/zod-validator, @hono/valibot-validator, etc.) has slightly different APIs
Prevention: This skill provides consistent patterns for all validators
错误现象:不同验证库的钩子模式不一致
来源:Context7研究
原因:每个验证库(@hono/zod-validator、@hono/valibot-validator等)的API略有不同
解决方法:本技能提供了所有验证库的统一使用模式
Issue #4: HTTPException Misuse
问题4:HTTPException误用
Error: Throwing plain Error instead of HTTPException
Source: Official docs
Why It Happens: Developers familiar with Express use
Prevention: Always use for client errors (400-499)
throw new Error()HTTPExceptiontypescript
// ❌ Wrong
throw new Error('Unauthorized')
// ✅ Correct
throw new HTTPException(401, { message: 'Unauthorized' })错误现象:抛出普通Error而非HTTPException
来源:官方文档
原因:熟悉Express的开发者习惯使用
解决方法:客户端错误(400-499)始终使用HTTPException
throw new Error()typescript
// ❌ 错误用法
throw new Error('未授权')
// ✅ 正确用法
throw new HTTPException(401, { message: '未授权' })Issue #5: Context Type Safety Lost
问题5:上下文类型安全丢失
Error: and without type inference
Source: Official docs
Why It Happens: Not defining type in Hono generic
Prevention: Always define Variables type
c.set()c.get()Variablestypescript
type Variables = {
user: { id: number; name: string }
}
const app = new Hono<{ Variables: Variables }>()错误现象:和无类型推断
来源:官方文档
原因:未在Hono泛型中定义类型
解决方法:始终定义Variables类型
c.set()c.get()Variablestypescript
type Variables = {
user: { id: number; name: string }
}
const app = new Hono<{ Variables: Variables }>()Issue #6: Missing Error Check After Middleware
问题6:中间件执行后未检查错误
Error: Errors in handlers not caught
Source: Official docs
Why It Happens: Not checking after
Prevention: Check in middleware
c.errorawait next()c.errortypescript
app.use('*', async (c, next) => {
await next()
if (c.error) {
console.error('Error:', c.error)
}
})错误现象:处理器中的错误未被捕获
来源:官方文档
原因:调用后未检查
解决方法:在中间件中检查
await next()c.errorc.errortypescript
app.use('*', async (c, next) => {
await next()
if (c.error) {
console.error('错误信息:', c.error)
}
})Issue #7: Direct Request Access Without Validation
问题7:未验证直接访问请求数据
Error: Accessing or without validation
Source: Best practices
Why It Happens: Developers skip validation for speed
Prevention: Always use validators and
c.req.param()c.req.query()c.req.valid()typescript
// ❌ 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
})错误现象:未验证直接访问或
来源:最佳实践
原因:开发者为了快速开发跳过验证
解决方法:始终使用验证器和
c.req.param()c.req.query()c.req.valid()typescript
// ❌ 错误用法
const id = c.req.param('id') // 字符串,无验证
// ✅ 正确用法
app.get('/users/:id', zValidator('param', idSchema), (c) => {
const { id } = c.req.valid('param') // 已验证的UUID
})Issue #8: Incorrect Middleware Order
问题8:中间件顺序错误
Error: Middleware executing in wrong order
Source: Official docs
Why It Happens: Misunderstanding middleware chain execution
Prevention: Remember middleware runs top-to-bottom, runs handler, then bottom-to-top
await next()typescript
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错误现象:中间件执行顺序不符合预期
来源:官方文档
原因:对中间件链的执行顺序理解有误
解决方法:记住中间件从上到下执行,执行处理器,然后从下到上执行后续逻辑
await next()typescript
app.use('*', async (c, next) => {
console.log('1: 处理器执行前')
await next()
console.log('4: 处理器执行后')
})
app.use('*', async (c, next) => {
console.log('2: 处理器执行前')
await next()
console.log('3: 处理器执行后')
})
app.get('/', (c) => {
console.log('处理器执行')
return c.json({})
})
// 输出顺序:1, 2, 处理器执行, 3, 4Configuration Files Reference
配置文件参考
package.json (Full Example)
package.json(完整示例)
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"
}
}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 with Validation (Zod)
包含Zod验证的package.json
json
{
"dependencies": {
"hono": "^4.10.2",
"zod": "^4.1.12",
"@hono/zod-validator": "^0.7.4"
}
}json
{
"dependencies": {
"hono": "^4.10.2",
"zod": "^4.1.12",
"@hono/zod-validator": "^0.7.4"
}
}package.json with Validation (Valibot)
包含Valibot验证的package.json
json
{
"dependencies": {
"hono": "^4.10.2",
"valibot": "^1.1.0",
"@hono/valibot-validator": "^0.5.3"
}
}json
{
"dependencies": {
"hono": "^4.10.2",
"valibot": "^1.1.0",
"@hono/valibot-validator": "^0.5.3"
}
}package.json with All Validators
包含所有验证器的package.json
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"
}
}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
tsconfig.json
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"]
}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"]
}File Templates
文件模板
All templates are available in the directory:
templates/- routing-patterns.ts - Route params, query params, wildcards, grouping
- middleware-composition.ts - Middleware chaining, built-in middleware
- validation-zod.ts - Zod validation with custom hooks
- validation-valibot.ts - Valibot validation
- rpc-pattern.ts - Type-safe RPC client/server
- error-handling.ts - HTTPException, onError, custom errors
- context-extension.ts - c.set/c.get, custom context types
- package.json - All dependencies
Copy these files to your project and customize as needed.
所有模板文件均位于目录下:
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 - 所有依赖配置
可将这些文件复制到你的项目中并按需自定义。
Reference Documentation
参考文档
For deeper understanding, see:
- middleware-catalog.md - Complete built-in Hono middleware reference
- validation-libraries.md - Zod vs Valibot vs Typia vs ArkType comparison
- rpc-guide.md - RPC pattern deep dive, performance optimization
- top-errors.md - Common Hono errors with solutions
如需深入了解,请查看:
- middleware-catalog.md - 完整的Hono内置中间件参考
- validation-libraries.md - Zod、Valibot、Typia、ArkType的对比分析
- rpc-guide.md - RPC模式深入解析、性能优化
- top-errors.md - 常见Hono错误及解决方案
Official Documentation
官方文档
- Hono: https://hono.dev
- Hono Routing: https://hono.dev/docs/api/routing
- Hono Middleware: https://hono.dev/docs/guides/middleware
- Hono Validation: https://hono.dev/docs/guides/validation
- Hono RPC: https://hono.dev/docs/guides/rpc
- Hono Context: https://hono.dev/docs/api/context
- Context7 Library ID:
/llmstxt/hono_dev_llms-full_txt
- 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
Dependencies (Latest Verified 2025-10-22)
依赖版本(2025-10-22最新验证)
json
{
"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"
}
}json
{
"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"
}
}Production Example
生产环境示例
This skill is validated across multiple runtime environments:
- Cloudflare Workers: Routing, middleware, RPC patterns
- Deno: All validation libraries tested
- Bun: Performance benchmarks completed
- Node.js: Full test suite passing
All patterns in this skill have been validated in production.
Questions? Issues?
- Check first
references/top-errors.md - Verify all steps in the setup process
- Ensure is called in middleware
await next() - Ensure RPC routes use pattern
const route = app.get(...) - Check official docs: https://hono.dev
本技能已在多个运行时环境中验证:
- Cloudflare Workers:路由、中间件、RPC模式均验证通过
- Deno:所有验证库测试通过
- Bun:性能基准测试完成
- Node.js:完整测试套件通过
本技能中的所有模式均已在生产环境中验证可行。
有疑问?遇到问题?
- 首先查看
references/top-errors.md - 验证设置过程中的所有步骤
- 确保中间件中调用了
await next() - 确保RPC路由使用的定义方式
const route = app.get(...) - 查看官方文档:https://hono.dev