关于 hono
Hono 是基于 Web 标准的轻量 Web 框架,面向构建边缘 API、BFF 和全栈应用的开发者。它支持多种运行时,并提供路由、中间件与类型化 RPC 客户端。
主要功能
- 01基于 Web 标准的请求与响应
- 02适配多种 JavaScript 运行时
- 03路由与中间件系统
- 04内置 JSX 支持
- 05类型化 RPC 客户端
适用场景
- 01构建边缘 REST 或 RPC API
- 02为 Bun 或 Node.js 创建类型安全服务
- 03开发低延迟 BFF
- 04在前后端共享类型化路由
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sickn33/ agentic-awesome-skills --skill hono安装后在 Claude Code 中输入/hono确认已加载。
详细介绍
Hono Web Framework
概述
Hono(炎,在日语中意为“火焰”)是一款基于 Web 标准(Request/Response/fetch)构建的小巧、超快速 Web 框架。它可在任何环境中运行:Cloudflare Workers、Deno Deploy、Bun、Node.js、AWS Lambda,以及任何兼容 WinterCG 的运行时,而且代码完全相同。Hono 的路由器是目前速度最快的路由器之一,其中间件系统、内置 JSX 支持和 RPC 客户端,使其成为边缘 API、BFF 和轻量级全栈应用的理想选择。
何时使用此技能
- 构建用于边缘部署(Cloudflare Workers、Deno Deploy)的 REST 或 RPC API 时
- 需要用于 Bun 或 Node.js 的精简且类型安全的服务端框架时
- 构建对延迟要求较低的前端后端服务(BFF)层时
- 从 Express 迁移,但希望获得更好的 TypeScript 支持和边缘兼容性时
- 用户询问 Hono 路由、中间件、
c.req、c.json或hc()RPC 客户端时
工作原理
第 1 步:项目设置
Cloudflare Workers(推荐用于边缘部署):
npm create hono@latest my-api
# Select: cloudflare-workers
cd my-api
npm install
npm run dev # Wrangler local dev
npm run deploy # Deploy to Cloudflare
Bun / Node.js:
mkdir my-api && cd my-api
bun init
bun add hono
// src/index.ts (Bun)
import { Hono } from 'hono';
const app = new Hono();
app.get('/', c => c.text('Hello Hono!'));
export default {
port: 3000,
fetch: app.fetch,
};
第 2 步:路由
import { Hono } from 'hono';
const app = new Hono();
// Basic methods
app.get('/posts', c => c.json({ posts: [] }));
app.post('/posts', c => c.json({ created: true }, 201));
app.put('/posts/:id', c => c.json({ updated: true }));
app.delete('/posts/:id', c => c.json({ deleted: true }));
// Route params and query strings
app.get('/posts/:id', async c => {
const id = c.req.param('id');
const format = c.req.query('format') ?? 'json';
return c.json({ id, format });
});
// Wildcard
app.get('/static/*', c => c.text('static file'));
export default app;
链式路由:
app
.get('/users', listUsers)
.post('/users', createUser)
.get('/users/:id', getUser)
.patch('/users/:id', updateUser)
.delete('/users/:id', deleteUser);
第 3 步:中间件
Hono 中间件的工作方式与 fetch 拦截器完全相同——在处理程序执行前后运行:
import { Hono } from 'hono';
import { logger } from 'hono/logger';
import { cors } from 'hono/cors';
import { bearerAuth } from 'hono/bearer-auth';
const app = new Hono<{ Variables: { requestId: string } }>();
// Built-in middleware
app.use('*', logger());
app.use('/api/*', cors({ origin: 'https://myapp.com' }));
app.use('/api/admin/*', bearerAuth({ token: process.env.API_TOKEN! }));
// Custom middleware
app.use('*', async (c, next) => {
c.set('requestId', crypto.randomUUID());
await next();
c.header('X-Request-Id', c.get('requestId'));
});
可用的内置中间件: logger、cors、csrf、etag、cache、basicAuth、bearerAuth、jwt、compress、bodyLimit、timeout、prettyJSON、secureHeaders。
以下内容列出的是可选的解析/响应方法,并非按顺序执行的处理程序:根据 Content-Type 解析一次请求正文,在运行时进行校验,并且只返回一个响应。从 hono/cookie 导入 getCookie。JSON 泛型不会校验输入。对 D1 和发布变更进行校验/授权,限制正文大小,只返回获准公开的字段,并处理错误。Bearer/JWT 代码片段需要配置强密钥和算法,并根据部署环境检查声明/过期时间/受众/签发者;请核实所安装 Hono 主版本对应的准确 API。在 Workers 中使用 c.env 绑定,而不要采用 Node 的 process.env 示例。CORS 不等于授权;脚手架提供的部署命令会发布实际资源,因此必须使用经过批准的账号/路由。
第 4 步:请求和响应辅助方法
app.post('/submit', async c => {
// Parse body
const body = await c.req.json<{ name: string; email: string }>();
const form = await c.req.formData();
const text = await c.req.text();
// Headers and cookies
const auth = c.req.header('authorization');
const token = getCookie(c, 'session');
// Responses
return c.json({ ok: true }); // JSON
return c.text('hello'); // plain text
return c.html('<h1>Hello</h1>'); // HTML
return c.redirect('/dashboard', 302); // redirect
return new Response(stream, { status: 200 }); // raw Response
});
第 5 步:Zod 校验器中间件
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';
const createPostSchema = z.object({
title: z.string().min(1).max(200),
body: z.string().min(1),
tags: z.array(z.string()).default([]),
});
app.post(
'/posts',
zValidator('json', createPostSchema),
async c => {
const data = c.req.valid('json'); // fully typed
const post = await db.post.create({ data });
return c.json(post, 201);
}
);
第 6 步:路由组和应用组合
// src/routes/posts.ts
import { Hono } from 'hono';
const posts = new Hono();
posts.get('/', async c => { /* list posts */ });
posts.post('/', async c => { /* create post */ });
posts.get('/:id', async c => { /* get post */ });
export default posts;
// src/index.ts
import { Hono } from 'hono';
import posts from './routes/posts';
import users from './routes/users';
const app = new Hono().basePath('/api');
app.route('/posts', posts);
app.route('/users', users);
export default app;
第 7 步:RPC 客户端(端到端类型安全)
Hono 的 RPC 模式会导出路由类型,供 hc 客户端使用——类似于 tRPC,但采用 fetch 约定:
// server: src/routes/posts.ts
import { Hono } from 'hono';
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';
const posts = new Hono()
.get('/', c => c.json({ posts: [{ id: '1', title: 'Hello' }] }))
.post(
'/',
zValidator('json', z.object({ title: z.string() })),
async c => {
const { title } = c.req.valid('json');
return c.json({ id: '2', title }, 201);
}
);
export default posts;
export type PostsType = typeof posts;
// client: src/client.ts
import { hc } from 'hono/client';
import type { PostsType } from '../server/routes/posts';
const client = hc<PostsType>('/api/posts');
// Fully typed — autocomplete on routes, params, and responses
const response = await client.$get();
if (!response.ok) throw new Error(`Request failed: ${response.status}`);
const { posts } = await response.json();
const created = await client.$post({ json: { title: 'New Post' } });
const newPost = await created.json();
示例
示例 1:JWT 身份验证中间件
import { Hono } from 'hono';
import { jwt, sign } from 'hono/jwt';
const app = new Hono();
const SECRET = process.env.JWT_SECRET!;
app.post('/login', async c => {
const { email, password } = await c.req.json();
const user = await validateUser(email, password);
if (!user) return c.json({ error: 'Invalid credentials' }, 401);
const token = await sign({ sub: user.id, exp: Math.floor(Date.now() / 1000) + 3600 }, SECRET);
return c.json({ token });
});
app.use('/api/*', jwt({ secret: SECRET }));
app.get('/api/me', async c => {
const payload = c.get('jwtPayload');
const user = await getUserById(payload.sub);
return c.json(user);
});
export default app;
示例 2:使用 D1 数据库的 Cloudflare Workers
// src/index.ts
import { Hono } from 'hono';
type Bindings = {
DB: D1Database;
API_TOKEN: string;
};
const app = new Hono<{ Bindings: Bindings }>();
app.get('/users', async c => {
const { results } = await c.env.DB.prepare('SELECT * FROM users LIMIT 50').all();
return c.json(results);
});
app.post('/users', async c => {
const { name, email } = await c.req.json();
await c.env.DB.prepare('INSERT INTO users (name, email) VALUES (?, ?)')
.bind(name, email)
.run();
return c.json({ created: true }, 201);
});
export default app;
示例 3:流式响应
import { stream, streamText } from 'hono/streaming';
app.get('/stream', c =>
streamText(c, async stream => {
for (const chunk of ['Hello', ' ', 'World']) {
await stream.write(chunk);
await stream.sleep(100);
}
})
);
最佳实践
- ✅ 使用路由组(子应用),将处理程序放在不同文件中——
app.route('/users', usersRouter) - ✅ 使用
zValidator校验所有请求正文、查询参数和路径参数 - ✅ 使用
Bindings泛型为 Cloudflare Workers 绑定指定类型:new Hono<{ Bindings: Env }>() - ✅ 前端和后端位于同一代码仓库时,使用 RPC 客户端(
hc) - ✅ 优先使用
c.json()/c.text(),而不是new Response(),让代码更简洁 - ❌ 如果需要边缘可移植性,请勿使用 Node.js 专用 API(
fs、path、process) - ❌ 不要添加沉重的依赖项——Hono 的优势在于其在边缘运行时中占用空间极小
- ❌ 不要跳过中间件类型定义——使用泛型(
Variables、Bindings),确保c.get()类型安全
安全与防护说明
- 使用请求中的数据前,务必先通过
zValidator验证输入。 - 提供 HTML/表单时,在变更端点上使用 Hono 内置的
csrf中间件。 - 对于 Cloudflare Workers,将非机密配置存储在
wrangler.toml的[vars]中,并使用wrangler secret put存储机密——切勿将其硬编码到源代码中。 - 使用
bearerAuth或jwt时,确保在服务端验证令牌——不要信任客户端提供的用户 ID。 - 使用 Cloudflare Rate Limiting 或自定义中间件,对敏感端点(身份验证、密码重置)进行速率限制。
常见问题
-
问题: 处理程序返回
undefined——响应为空 解决方案: 处理程序务必return一个响应:使用return c.json(...),而不只是c.json(...)。 -
问题: 响应发送后才运行中间件 解决方案: 在响应后的逻辑之前调用
await next();Hono 会在响应沿调用链返回时运行next()之后的代码。 -
问题: 在 Node.js 上
c.env未定义 解决方案: Cloudflare 的env绑定仅存在于 Workers 中。在 Node.js 上使用process.env。 -
问题: 路由未匹配——收到 404 解决方案: 检查
app.route('/prefix', subRouter)使用的前缀是否与客户端调用的前缀相同。子路由不应在自身路由中重复此前缀。
相关技能
@cloudflare-workers-expert— 深入了解 Cloudflare Workers 平台特性@trpc-fullstack— TypeScript 全栈应用的另一种 RPC 方案@zod-validation-expert— 使用@hono/zod-validator时的详细 Zod 模式@nodejs-backend-patterns— 需要 Node.js 专用后端(而非边缘端)时使用
限制
- 仅当任务明确符合上述范围时,才使用此技能。
- 不要将输出视为环境特定验证、测试或专家审查的替代品。
- 如果缺少必要的输入、权限、安全边界或成功标准,请停止并请求澄清。