其他
需要构建可跨 Cloudflare Workers…
适用于需要多运行时可移植、边缘计算或轻量高性能 API 的 Web 应用开发。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 35/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 39/100 ×0.15
适用场景
需要构建可跨 Cloudflare Wo特定
解决思路
- 安装 Hono:使用 `npm create hono@latest my-app` 创建新项目,或在现有项目中执行 `npm install hono`;Node.js 环境额外安装 `npm install @hono/node-server`。
- 创建应用:`import { Hono } from 'hono'`;`const app = new Hono()`;`app.get('/', (c) => c.text('Hello Hono!'))`;`export default app`。
- 使用 TypeScript 泛型定义 Bindings 和 Variables:`type Bindings = { DATABASE_URL: string; API_KEY: string }`;`type Variables = { user: { id: string; name: string } }`;`const app = new Hono<{ Bindings: Bindings; Variables: Variables }>()`。
- 通过上下文对象 `c` 读取请求数据:`c.req.param('id')` 获取路径参数;`c.req.query('sort')` 获取查询参数;`c.req.queries('tags')` 获取多个同名查询参数;`c.req.header('Authorization')` 获取请求头;`await c.req.json()` 解析 JSON 请求体;`await c.req.formData()` 解析表单数据。
- 通过 `c.env.DATABASE_URL` 访问环境绑定(如 Cloudflare Workers bindings),通过 `c.get('user')` 读取中间件设置的变量。
- 使用响应方法返回响应:`c.text('Plain text')`、`c.json({ id, name: 'User' })`、`c.html('<h1>Hello</h1>')`、`c.redirect('/login')`、`c.notFound()`。
- 响应方法可带状态码和头部:`c.text('Hello', 200)`;`c.json({ message: 'Success' }, 201)`;`c.json({ error: 'Not found' }, 404)`;`c.html('<h1>Hello</h1>')`;`c.redirect('/login')`(302)或 `c.redirect('/login', 301)`;`c.header('X-Custom', 'value')`;`c.header('Cache-Control', 'max-age=3600')`。
- 使用流式响应:`c.streamText(async (stream) => { await stream.write('Hello '); await stream.write('World!') })`。
- 返回原始 Response:`return new Response('Raw', { status: 200 })`。
- 基础路由:使用 `app.get('/users', getUsers)`、`app.post('/users', createUser)`、`app.put('/users/:id', updateUser)`、`app.delete('/users/:id', deleteUser)`、`app.patch('/users/:id', patchUser)`;用 `app.all('/webhook', handleWebhook)` 处理所有方法;用 `app.on('PURGE', '/cache', purgeCache)` 处理自定义方法;用 `app.on(['GET', 'POST'], '/form', handleForm)` 处理多个方法。
- 路径参数:单参数用 `app.get('/users/:id', (c) => { const id = c.req.param('id'); return c.json({ id }) })`;多参数用 `app.get('/posts/:postId/comments/:commentId', (c) => { const { postId, commentId } = c.req.param(); return c.json({ postId, commentId }) })`;可选参数用 `app.get('/api/animal/:type?', (c) => { const type = c.req.param('type') || 'all'; return c.json({ type }) })`;正则验证用 `app.get('/posts/:id{[0-9]+}', (c) => { const id = c.req.param('id'); return c.json({ id }) })`;通配符用 `app.get('/files/*', (c) => { const path = c.req.param('*'); return c.text(`File: ${path}`) })`。
- 路由分组:用 `app.route('/api/v1', api)` 挂载子应用;用 `const v2 = new Hono().basePath('/api/v2')` 设置基础路径;支持链式调用如 `app.get('/a', handlerA).post('/b', handlerB).delete('/c', handlerC)`。
- 多文件路由组织:在 `routes/users.ts` 中 `import { Hono } from 'hono'`,`const users = new Hono()`,定义 `users.get('/', ...)`、`users.post('/', ...)`、`users.get('/:id', ...)`,`export default users`;在 `app.ts` 中 import 后 `app.route('/users', users)`、`app.route('/posts', posts)`。
- 内联处理程序:简单处理用 `app.get('/hello', (c) => c.text('Hello!'))`;异步处理用 `app.get('/users', async (c) => { const users = await fetchUsers(); return c.json({ users }) })`;多个处理程序链用 `app.get('/admin', authenticate, authorize, (c) => { return c.json({ admin: true }) })`。
- 使用 Factory 创建类型安全处理程序:`import { createFactory } from 'hono/factory'`;`const factory = createFactory<{ Bindings: Bindings }>()`;`const getUser = factory.createHandlers(async (c) => { const id = c.req.param('id'); const db = c.env.DATABASE_URL; return c.json({ id }) })`;`app.get('/users/:id', ...getUser)`。
- 内置错误处理:`import { HTTPException } from 'hono/http-exception'`;抛出 `throw new HTTPException(404, { message: 'User not found' })`;全局错误处理用 `app.onError((err, c) => { console.error(`${err}`); if (err instanceof HTTPException) { return err.getResponse() } return c.json({ error: 'Internal Server Error' }, 500) })`;404 处理用 `app.notFound((c) => { return c.json({ error: 'Route not found' }, 404) })`。
- 自定义错误类:继承 HTTPException,例如 `class ValidationError extends HTTPException { constructor(errors: string[]) { super(400, { message: 'Validation failed', cause: errors }) } }` 和 `class AuthenticationError extends HTTPException { constructor() { super(401, { message: 'Authentication required' }) } }`。
- 运行时特定导出:Cloudflare Workers 用 `export default app`;Node.js 用 `import { serve } from '@hono/node-server'`,`serve({ fetch: app.fetch, port: 3000 })`;Bun 用 `export default { port: 3000, fetch: app.fetch }`;Deno 用 `import { Hono } from 'npm:hono'`,`Deno.serve(app.fetch)`。
- 最佳实践:写处理程序时内联(而非控制器类),以保留类型推断,例如 `app.get('/users/:id', async (c) => { const id = c.req.param('id'); return c.json({ id }) })`,避免 `class UserController { getUser(c: Context) { ... } }`;使用模块化路由,如 `export const users = new Hono().get('/', listUsers).post('/', createUser).get('/:id', getUser)`,然后 `app.route('/users', users)`;类型化一切,定义 `type Bindings = { DATABASE_URL: string; JWT_SECRET: string; MY_KV: KVNamespace }` 并传入 `new Hono<{ Bindings: Bindings }>()`,使 `c.env` 完全类型化。
- 快速参考:常用 Context 方法包括 `c.req.param(name)`、`c.req.query(name)`、`c.req.header(name)`、`await c.req.json()`、`await c.req.formData()`、`c.text(str, status)`、`c.json(obj, status)`、`c.html(str)`、`c.redirect(url)`、`c.header(k, v)`、`c.set(key, val)`、`c.get(key)`、`c.env`;HTTP 方法包括 `app.get(path, ...handlers)`、`app.post(path, ...handlers)`、`app.put(path, ...handlers)`、`app.delete(path, ...handlers)`、`app.patch(path, ...handlers)`、`app.options(path, ...handlers)`、`app.head(path, ...handlers)`、`app.all(path, ...handlers)`、`app.on(method, path, ...handlers)`。
适用边界 · 注意事项
- 如果需要 Node.js 专属且庞大的生态系统,Express 可能更合适。
- 如果仅针对 Bun 运行且偏好 Elysia 的 API 风格,则不必用 Hono。
- 如果仅针对 Node.js 且需要 Fastify 的 schema-based 特性,可考虑 Fastify。