hono-api-scaffolder by jezweb/claude-skills
npx skills add https://github.com/jezweb/claude-skills --skill hono-api-scaffolder为现有的 Cloudflare Workers 项目添加结构化的 API 路由。此技能在项目外壳存在后运行(通过 cloudflare-worker-builder 或 vite-flare-starter),并生成路由文件、中间件和端点文档。
确定 API 需要什么。可以询问用户或从项目描述中推断。按资源对端点进行分组:
Users: GET /api/users, GET /api/users/:id, POST /api/users, PUT /api/users/:id, DELETE /api/users/:id
Posts: GET /api/posts, GET /api/posts/:id, POST /api/posts, PUT /api/posts/:id
Auth: POST /api/auth/login, POST /api/auth/logout, GET /api/auth/me
每个资源组一个文件。使用 assets/route-template.ts 中的模板:
// src/routes/users.ts
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
import type { Env } from '../types'
const app = new Hono<{ Bindings: Env }>()
// GET /api/users
app.get('/', async (c) => {
const db = c.env.DB
const { results } = await db.prepare('SELECT * FROM users').all()
return c.json({ users: results })
})
// GET /api/users/:id
app.get('/:id', async (c) => {
const id = c.req.param('id')
const user = await db.prepare('SELECT * FROM users WHERE id = ?').bind(id).first()
if (!user) return c.json({ error: 'Not found' }, 404)
return c.json({ user })
})
// POST /api/users
const createUserSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
})
app.post('/', zValidator('json', createUserSchema), async (c) => {
const body = c.req.valid('json')
// ... 插入逻辑
return c.json({ user }, 201)
})
export default app
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
根据项目需求,从 assets/middleware-template.ts 添加:
认证中间件 — 保护需要身份验证的路由:
import { createMiddleware } from 'hono/factory'
import type { Env } from '../types'
export const requireAuth = createMiddleware<{ Bindings: Env }>(async (c, next) => {
const token = c.req.header('Authorization')?.replace('Bearer ', '')
if (!token) return c.json({ error: 'Unauthorized' }, 401)
// 验证令牌...
await next()
})
CORS — 使用 Hono 内置的:
import { cors } from 'hono/cors'
app.use('/api/*', cors({ origin: ['https://example.com'] }))
在主入口点挂载所有路由组:
// src/index.ts
import { Hono } from 'hono'
import type { Env } from './types'
import users from './routes/users'
import posts from './routes/posts'
import auth from './routes/auth'
import { errorHandler } from './middleware/error-handler'
const app = new Hono<{ Bindings: Env }>()
// 全局错误处理器
app.onError(errorHandler)
// 挂载路由
app.route('/api/users', users)
app.route('/api/posts', posts)
app.route('/api/auth', auth)
// 健康检查
app.get('/api/health', (c) => c.json({ status: 'ok' }))
export default app
// src/types.ts
export interface Env {
DB: D1Database
KV: KVNamespace // 如果需要
R2: R2Bucket // 如果需要
API_SECRET: string // 密钥
}
记录所有端点。格式请参考 references/endpoint-docs-template.md:
## POST /api/users
创建新用户。
- **认证**:必需(Bearer 令牌)
- **请求体**:`{ name: string, email: string }`
- **响应 201**:`{ user: User }`
- **响应 400**:`{ error: string, details: ZodError }`
始终使用 @hono/zod-validator 验证请求体:
import { zValidator } from '@hono/zod-validator'
app.post('/', zValidator('json', schema), async (c) => {
const body = c.req.valid('json') // 完全类型化
})
安装:pnpm add @hono/zod-validator zod
使用 assets/error-handler.ts 中的标准错误处理器:
export const errorHandler = (err: Error, c: Context) => {
console.error(err)
return c.json({ error: err.message }, 500)
}
API 路由必须返回 JSON 错误,而不是重定向。 fetch() 会静默跟随重定向,然后客户端会尝试将 HTML 解析为 JSON。
为了在 Worker 和客户端之间实现端到端的类型安全:
// Worker: 导出应用类型
export type AppType = typeof app
// Client: 使用 hc (Hono Client)
import { hc } from 'hono/client'
import type { AppType } from '../worker/src/index'
const client = hc<AppType>('https://api.example.com')
const res = await client.api.users.$get() // 完全类型化
| 项目规模 | 结构 |
|---|---|
| < 10 个端点 | 包含所有路由的单个 index.ts |
| 10-30 个端点 | 每个资源一个路由文件 (routes/users.ts) |
| 30+ 个端点 | 路由文件 + 共享中间件 + 类型化上下文 |
| 何时使用 | 阅读 |
|---|---|
| Hono 模式、中间件、RPC | references/hono-patterns.md |
| API_ENDPOINTS.md 格式 | references/endpoint-docs-template.md |
| 文件 | 用途 |
|---|---|
| assets/route-template.ts | 包含 CRUD + Zod 的起始路由文件 |
| assets/middleware-template.ts | 认证中间件模板 |
| assets/error-handler.ts | 标准 JSON 错误处理器 |
每周安装量
473
代码仓库
GitHub 星标数
643
首次出现
2026年2月18日
安全审计
安装于
opencode432
codex428
github-copilot427
gemini-cli426
cursor420
kimi-cli415
Add structured API routes to an existing Cloudflare Workers project. This skill runs AFTER the project shell exists (via cloudflare-worker-builder or vite-flare-starter) and produces route files, middleware, and endpoint documentation.
Determine what the API needs. Either ask the user or infer from the project description. Group endpoints by resource:
Users: GET /api/users, GET /api/users/:id, POST /api/users, PUT /api/users/:id, DELETE /api/users/:id
Posts: GET /api/posts, GET /api/posts/:id, POST /api/posts, PUT /api/posts/:id
Auth: POST /api/auth/login, POST /api/auth/logout, GET /api/auth/me
One file per resource group. Use the template from assets/route-template.ts:
// src/routes/users.ts
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
import type { Env } from '../types'
const app = new Hono<{ Bindings: Env }>()
// GET /api/users
app.get('/', async (c) => {
const db = c.env.DB
const { results } = await db.prepare('SELECT * FROM users').all()
return c.json({ users: results })
})
// GET /api/users/:id
app.get('/:id', async (c) => {
const id = c.req.param('id')
const user = await db.prepare('SELECT * FROM users WHERE id = ?').bind(id).first()
if (!user) return c.json({ error: 'Not found' }, 404)
return c.json({ user })
})
// POST /api/users
const createUserSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
})
app.post('/', zValidator('json', createUserSchema), async (c) => {
const body = c.req.valid('json')
// ... insert logic
return c.json({ user }, 201)
})
export default app
Based on project needs, add from assets/middleware-template.ts:
Auth middleware — protect routes requiring authentication:
import { createMiddleware } from 'hono/factory'
import type { Env } from '../types'
export const requireAuth = createMiddleware<{ Bindings: Env }>(async (c, next) => {
const token = c.req.header('Authorization')?.replace('Bearer ', '')
if (!token) return c.json({ error: 'Unauthorized' }, 401)
// Validate token...
await next()
})
CORS — use Hono's built-in:
import { cors } from 'hono/cors'
app.use('/api/*', cors({ origin: ['https://example.com'] }))
Mount all route groups in the main entry point:
// src/index.ts
import { Hono } from 'hono'
import type { Env } from './types'
import users from './routes/users'
import posts from './routes/posts'
import auth from './routes/auth'
import { errorHandler } from './middleware/error-handler'
const app = new Hono<{ Bindings: Env }>()
// Global error handler
app.onError(errorHandler)
// Mount routes
app.route('/api/users', users)
app.route('/api/posts', posts)
app.route('/api/auth', auth)
// Health check
app.get('/api/health', (c) => c.json({ status: 'ok' }))
export default app
// src/types.ts
export interface Env {
DB: D1Database
KV: KVNamespace // if needed
R2: R2Bucket // if needed
API_SECRET: string // secrets
}
Document all endpoints. See references/endpoint-docs-template.md for the format:
## POST /api/users
Create a new user.
- **Auth**: Required (Bearer token)
- **Body**: `{ name: string, email: string }`
- **Response 201**: `{ user: User }`
- **Response 400**: `{ error: string, details: ZodError }`
Always validate request bodies with @hono/zod-validator:
import { zValidator } from '@hono/zod-validator'
app.post('/', zValidator('json', schema), async (c) => {
const body = c.req.valid('json') // fully typed
})
Install: pnpm add @hono/zod-validator zod
Use the standard error handler from assets/error-handler.ts:
export const errorHandler = (err: Error, c: Context) => {
console.error(err)
return c.json({ error: err.message }, 500)
}
API routes must return JSON errors, not redirects. fetch() follows redirects silently, then the client tries to parse HTML as JSON.
For end-to-end type safety between Worker and client:
// Worker: export the app type
export type AppType = typeof app
// Client: use hc (Hono Client)
import { hc } from 'hono/client'
import type { AppType } from '../worker/src/index'
const client = hc<AppType>('https://api.example.com')
const res = await client.api.users.$get() // fully typed
| Project size | Structure |
|---|---|
| < 10 endpoints | Single index.ts with all routes |
| 10-30 endpoints | Route files per resource (routes/users.ts) |
| 30+ endpoints | Route files + shared middleware + typed context |
| When | Read |
|---|---|
| Hono patterns, middleware, RPC | references/hono-patterns.md |
| API_ENDPOINTS.md format | references/endpoint-docs-template.md |
| File | Purpose |
|---|---|
| assets/route-template.ts | Starter route file with CRUD + Zod |
| assets/middleware-template.ts | Auth middleware template |
| assets/error-handler.ts | Standard JSON error handler |
Weekly Installs
473
Repository
GitHub Stars
643
First Seen
Feb 18, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode432
codex428
github-copilot427
gemini-cli426
cursor420
kimi-cli415
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
138,300 周安装