api-framework-hono
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAPI Development with Hono + OpenAPI
使用 Hono + OpenAPI 进行 API 开发
Quick Guide: Use Hono withfor type-safe REST APIs that auto-generate OpenAPI specs. Import@hono/zod-openapifromz(NOT from@hono/zod-openapi) sozodis available on all schemas. Always include.openapi()in routes and export theoperationIdinstance for spec generation.app
<critical_requirements>
快速指南: 使用 Hono 搭配构建可自动生成 OpenAPI 规范的类型安全 REST API。从@hono/zod-openapi导入@hono/zod-openapi(而非从z导入),这样所有 schema 都能使用zod方法。务必在路由中包含.openapi(),并导出operationId实例以生成规范。app
<critical_requirements>
CRITICAL: Before Using This Skill
关键要求:使用本技能前须知
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,, named constants)import type
(You MUST import from , NOT from -- this gives Zod the method)
z@hono/zod-openapizod.openapi()(You MUST export the instance for OpenAPI spec generation)
app(You MUST include in every route for clean client generation)
operationId</critical_requirements>
Auto-detection: Hono, @hono/zod-openapi, OpenAPIHono, createRoute, Zod schemas with .openapi(), app.route(), createMiddleware, rate limiting, CORS configuration, health checks, hc client, RPC mode, getContext, tryGetContext, contextStorage, some/every/except middleware
When to use:
- Building type-safe REST APIs with auto-generated OpenAPI specs
- Defining OpenAPI specifications with automatic Zod validation
- Creating standardized error responses with proper status codes
- Implementing filtering, pagination, and sorting patterns
- Public or multi-client APIs needing formal documentation
- Production APIs requiring rate limiting, CORS, health checks
When NOT to use:
- Simple CRUD with no external consumers (framework-native endpoints are simpler)
- Internal-only APIs without documentation requirements
- Single-use endpoints with no schema reuse (over-engineering)
Key patterns covered:
- Modular route setup with and
app.route()OpenAPIHono - Zod schema definitions with metadata
.openapi() - Route definition with (operationId, tags, responses)
createRoute - Error handling with named error codes
- Filtering, pagination, and data transformation
- Auth, rate limiting, CORS, logging, caching middleware
- Health check endpoints (shallow and deep)
- RPC client () with end-to-end type safety
hc - Context Storage for out-of-handler context access
- Combine Middleware (/
some/every) for declarative authexcept
Detailed Resources:
- examples/core.md - Route setup, list/detail endpoints
- examples/validation.md - Zod schema definitions with OpenAPI
- examples/routes.md - Filtering, pagination, data transformation
- examples/middleware.md - Auth, rate limiting, CORS, logging, caching
- examples/error-handling.md - Standardized error responses
- examples/openapi.md - Spec generation (build-time and endpoint)
- examples/health-checks.md - Liveness and readiness checks
- examples/advanced-v4.md - RPC, Context Storage, Combine Middleware
- reference.md - Decision frameworks, anti-patterns, production checklist
<philosophy>
所有代码必须遵循 CLAUDE.md 中的项目约定(短横线命名、具名导出、导入顺序、、具名常量)import type
(必须从 导入 ,而非从 导入——这会为 Zod 提供 方法)
@hono/zod-openapizzod.openapi()(必须导出 实例以生成 OpenAPI 规范)
app(必须在每个路由中包含 ,以生成简洁的客户端代码)
operationId</critical_requirements>
自动检测范围: Hono、@hono/zod-openapi、OpenAPIHono、createRoute、带 .openapi() 的 Zod schema、app.route()、createMiddleware、限流、CORS 配置、健康检查、hc 客户端、RPC 模式、getContext、tryGetContext、contextStorage、some/every/except 中间件
适用场景:
- 构建可自动生成 OpenAPI 规范的类型安全 REST API
- 通过自动 Zod 验证定义 OpenAPI 规范
- 创建带有正确状态码的标准化错误响应
- 实现过滤、分页和排序模式
- 需要正式文档的公共或多客户端 API
- 需限流、CORS、健康检查的生产级 API
不适用场景:
- 无外部消费者的简单 CRUD(框架原生端点更简单)
- 无需文档的内部专属 API
- 无 schema 复用的一次性端点(过度设计)
涵盖的核心模式:
- 使用 和
app.route()的模块化路由设置OpenAPIHono - 带 元数据的 Zod schema 定义
.openapi() - 使用 的路由定义(operationId、标签、响应)
createRoute - 带命名错误码的错误处理
- 过滤、分页和数据转换
- 认证、限流、CORS、日志、缓存中间件
- 健康检查端点(浅度和深度)
- 具备端到端类型安全的 RPC 客户端()
hc - 用于处理器外上下文访问的 Context Storage
- 用于声明式认证的组合中间件(/
some/every)except
详细资源:
- examples/core.md - 路由设置、列表/详情端点
- examples/validation.md - 带 OpenAPI 的 Zod schema 定义
- examples/routes.md - 过滤、分页、数据转换
- examples/middleware.md - 认证、限流、CORS、日志、缓存
- examples/error-handling.md - 标准化错误响应
- examples/openapi.md - 规范生成(构建时和端点式)
- examples/health-checks.md - 存活和就绪检查
- examples/advanced-v4.md - RPC、Context Storage、组合中间件
- reference.md - 决策框架、反模式、生产环境检查清单
<philosophy>
Philosophy
设计理念
Type safety + documentation from code. Zod schemas serve both validation AND OpenAPI spec generation. Single source of truth flows to clients via generated SDKs or Hono's RPC client.
Use Hono + OpenAPI when: Building public/multi-client APIs, need auto-generated documentation, require formal OpenAPI specs, want type-safe validation.
Use simpler approaches when: Internal-only CRUD, no external API consumers, no documentation needs.
</philosophy>
<patterns>
类型安全 + 代码即文档。Zod schema 同时用于验证和 OpenAPI 规范生成。单一数据源通过生成的 SDK 或 Hono 的 RPC 客户端同步到客户端。
当使用 Hono + OpenAPI: 构建公共/多客户端 API、需要自动生成文档、要求正式 OpenAPI 规范、希望类型安全验证时。
当使用更简单方案: 内部专属 CRUD、无外部 API 消费者、无文档需求时。
</philosophy>
<patterns>
Core Patterns
核心模式
Pattern 1: Modular Route Setup
模式1:模块化路由设置
Structure routes using for modularization. Export the instance for spec generation.
app.route()apptypescript
import { OpenAPIHono } from "@hono/zod-openapi";
const app = new OpenAPIHono().basePath("/api");
app.route("/", jobsRoutes);
app.route("/", companiesRoutes);
// REQUIRED: Export app for spec generation
export { app };Why good: prevents God files, app export enables build-time spec generation
app.route()See examples/core.md for complete setup with framework adapter exports.
使用 构建模块化路由结构。导出 实例以生成规范。
app.route()apptypescript
import { OpenAPIHono } from "@hono/zod-openapi";
const app = new OpenAPIHono().basePath("/api");
app.route("/", jobsRoutes);
app.route("/", companiesRoutes);
// 必须:导出app以生成规范
export { app };优势: 避免巨型文件,app 导出支持构建时规范生成
app.route()查看 examples/core.md 获取包含框架适配器导出的完整设置。
Pattern 2: Zod Schemas with OpenAPI Metadata
模式2:带 OpenAPI 元数据的 Zod Schema
Import from (not ). Use for schema registration and documentation.
z@hono/zod-openapizod.openapi()typescript
import { z } from "@hono/zod-openapi";
const MIN_SALARY = 0;
const CURRENCY_CODE_LENGTH = 3;
export const SalarySchema = z
.object({
min: z.number().min(MIN_SALARY),
max: z.number().min(MIN_SALARY),
currency: z.string().length(CURRENCY_CODE_LENGTH),
})
.openapi("Salary", {
example: { min: 60000, max: 90000, currency: "EUR" },
});Why good: importing from provides automatically, named constants prevent magic number bugs, registers as
z@hono/zod-openapi.openapi().openapi("Name")#/components/schemas/NameSee examples/validation.md for complete schema patterns.
从 导入 (而非 )。使用 进行 schema 注册和文档化。
@hono/zod-openapizzod.openapi()typescript
import { z } from "@hono/zod-openapi";
const MIN_SALARY = 0;
const CURRENCY_CODE_LENGTH = 3;
export const SalarySchema = z
.object({
min: z.number().min(MIN_SALARY),
max: z.number().min(MIN_SALARY),
currency: z.string().length(CURRENCY_CODE_LENGTH),
})
.openapi("Salary", {
example: { min: 60000, max: 90000, currency: "EUR" },
});优势: 从 导入 会自动提供 ,具名常量避免魔法数字错误, 会注册为
@hono/zod-openapiz.openapi().openapi("Name")#/components/schemas/Name查看 examples/validation.md 获取完整的 schema 模式。
Pattern 3: Route Definition with createRoute
模式3:使用 createRoute 定义路由
Define routes with and implement with . Always include .
createRouteapp.openapi()operationIdtypescript
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
const getJobsRoute = createRoute({
method: "get",
path: "/jobs",
operationId: "getJobs", // Becomes client method name
tags: ["Jobs"],
request: { query: JobsQuerySchema },
responses: {
200: {
description: "List of jobs",
content: { "application/json": { schema: JobsResponseSchema } },
},
},
});
app.openapi(getJobsRoute, async (c) => {
const { country } = c.req.valid("query"); // Type-safe validated params
// ... handler logic
return c.json({ jobs: results }, 200);
});Why good: becomes clean client method name ( vs ), enforces schema validation with types
operationIdgetJobsget_api_jobsc.req.valid()See examples/core.md for list/detail endpoint examples.
使用 定义路由,并通过 实现。务必包含 。
createRouteapp.openapi()operationIdtypescript
import { OpenAPIHono, createRoute, z } from "@hono/zod-openapi";
const getJobsRoute = createRoute({
method: "get",
path: "/jobs",
operationId: "getJobs", // 成为客户端方法名
tags: ["Jobs"],
request: { query: JobsQuerySchema },
responses: {
200: {
description: "职位列表",
content: { "application/json": { schema: JobsResponseSchema } },
},
},
});
app.openapi(getJobsRoute, async (c) => {
const { country } = c.req.valid("query"); // 类型安全的验证参数
// ... 处理器逻辑
return c.json({ jobs: results }, 200);
});优势: 会成为简洁的客户端方法名( 而非 ), 强制 schema 验证并提供类型支持
operationIdgetJobsget_api_jobsc.req.valid()查看 examples/core.md 获取列表/详情端点示例。
Pattern 4: Error Handling with Named Codes
模式4:带命名错误码的错误处理
Use named error code constants for consistent, machine-parseable error responses.
typescript
export const ErrorCodes = {
VALIDATION_ERROR: "validation_error",
NOT_FOUND: "not_found",
UNAUTHORIZED: "unauthorized",
INTERNAL_ERROR: "internal_error",
} as const;Why good: Named codes enable frontend handling, consistent shape across all endpoints
switchSee examples/error-handling.md for the full utility.
handleRouteError使用命名错误码常量实现一致的、可机器解析的错误响应。
typescript
export const ErrorCodes = {
VALIDATION_ERROR: "validation_error",
NOT_FOUND: "not_found",
UNAUTHORIZED: "unauthorized",
INTERNAL_ERROR: "internal_error",
} as const;优势: 命名错误码支持前端 处理,所有端点保持一致的响应格式
switch查看 examples/error-handling.md 获取完整的 工具类。
handleRouteErrorPattern 5: JWT Authentication with Explicit Algorithm
模式5:带明确算法的 JWT 认证
Always specify the option on JWT/JWK middleware to prevent algorithm confusion attacks (CVE-2026-22817, CVE-2026-22818, patched in v4.11.4+).
algtypescript
import { verify } from "hono/jwt";
const JWT_ALGORITHM = "HS256";
const payload = await verify(token, secret, JWT_ALGORITHM);Why good: explicit algorithm prevents attackers from switching to symmetric verification with known public keys
See examples/middleware.md for complete auth middleware with type-safe variables.
</patterns>
<red_flags>
务必在 JWT/JWK 中间件中指定 选项,以防止算法混淆攻击(CVE-2026-22817、CVE-2026-22818,v4.11.4+ 已修复)。
algtypescript
import { verify } from "hono/jwt";
const JWT_ALGORITHM = "HS256";
const payload = await verify(token, secret, JWT_ALGORITHM);优势: 明确的算法可防止攻击者切换为使用已知公钥的对称验证
查看 examples/middleware.md 获取带类型安全变量的完整认证中间件。
</patterns>
<red_flags>
RED FLAGS
警示事项
High Priority:
- Importing from
zinstead of"zod"--"@hono/zod-openapi"won't be available.openapi() - Missing in routes -- generated client has ugly method names
operationId - Not exporting instance -- can't generate OpenAPI spec at build time
app - JWT/JWK without explicit option -- algorithm confusion vulnerability (CVE-2026-22817/22818)
alg
Medium Priority:
- Using /
c.req.param()instead ofc.req.query()-- bypasses Zod validationc.req.valid() - No pagination limits on list endpoints -- returns massive datasets
- Generating spec at runtime instead of build time -- wasted CPU per request
- Not returning proper status codes -- always specify (200, 404, 500)
- Wildcard CORS () with
"*"-- browsers reject this (spec violation)credentials: true
Gotchas & Edge Cases:
- uses singular
c.req.valid("param"), not"param"-- easy to mistype"params" - In-memory rate limiting doesn't work across multiple instances -- use a shared store
- CORS middleware must be registered before auth middleware -- OPTIONS preflight bypasses auth
- ETags should not be used for user-specific data (generates unique ETag per user)
- RPC routes must be chained () for type inference -- separate calls break it
.openapi(r1, h1).openapi(r2, h2) - Both client and server need
tsconfig.jsonfor RPC type inference"strict": true - middleware must be registered before any code calls
contextStorage()getContext() - Use (v4.11.0+) in code that may run outside request context (tests, background jobs)
tryGetContext() - Middleware never throws in Hono -- wrapping
next()in try/catch is unnecessaryawait next() - is adapter-specific -- import from
getConnInfo,hono/bun,hono/deno, etc. (NOT from@hono/node-server/conninfo)hono/ip-restriction
</red_flags>
<critical_reminders>
高优先级:
- 从 而非
"zod"导入"@hono/zod-openapi"——z方法不可用.openapi() - 路由中缺少 ——生成的客户端方法名不友好
operationId - 未导出 实例——无法在构建时生成 OpenAPI 规范
app - JWT/JWK 未指定明确的 选项——存在算法混淆漏洞(CVE-2026-22817/22818)
alg
中优先级:
- 使用 /
c.req.param()而非c.req.query()——绕过 Zod 验证c.req.valid() - 列表端点未设置分页限制——返回超大数据集
- 在运行时而非构建时生成规范——每次请求浪费 CPU
- 未返回正确的状态码——务必指定(200、404、500)
- 通配符 CORS()搭配
"*"——浏览器会拒绝此配置(违反规范)credentials: true
陷阱与边缘情况:
- 使用单数
c.req.valid("param"),而非"param"——容易拼写错误"params" - 内存限流在多实例环境下无效——使用共享存储
- CORS 中间件必须在认证中间件之前注册——OPTIONS 预检请求会绕过认证
- ETags 不应用于用户专属数据(会为每个用户生成唯一 ETag)
- RPC 路由必须链式调用()以实现类型推断——分开调用会破坏类型推断
.openapi(r1, h1).openapi(r2, h2) - 客户端和服务端的 都需要设置
tsconfig.json以实现 RPC 类型推断"strict": true - 中间件必须在任何调用
contextStorage()的代码之前注册getContext() - 在可能运行于请求上下文之外的代码(测试、后台任务)中使用 (v4.11.0+)
tryGetContext() - Hono 中的中间件 永远不会抛出异常——无需将
next()包裹在 try/catch 中await next() - 是适配器专属的——从
getConnInfo、hono/bun、hono/deno等导入(而非从@hono/node-server/conninfo)hono/ip-restriction
</red_flags>
<critical_reminders>
CRITICAL REMINDERS
关键提醒
All code must follow project conventions in CLAUDE.md
(You MUST import from , NOT from -- this gives Zod the method)
z@hono/zod-openapizod.openapi()(You MUST export the instance for OpenAPI spec generation)
app(You MUST include in every route for clean client generation)
operationIdFailure to follow these rules will break OpenAPI spec generation and type safety.
</critical_reminders>
所有代码必须遵循 CLAUDE.md 中的项目约定
(必须从 导入 ,而非从 导入——这会为 Zod 提供 方法)
@hono/zod-openapizzod.openapi()(必须导出 实例以生成 OpenAPI 规范)
app(必须在每个路由中包含 ,以生成简洁的客户端代码)
operationId不遵循这些规则会破坏 OpenAPI 规范生成和类型安全。
</critical_reminders>