From dev-skills
Develops server-side APIs with Nitro v3 and H3, including project initialization for pure backend or Vite full-stack, CRUD endpoints, Drizzle ORM database integration, and multi-platform deployment to Vercel or Cloudflare Workers.
How this skill is triggered — by the user, by Claude, or both
Slash command
/dev-skills:nitro-api-developmentThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
本技能用于指导使用 Nitro v3 框架编写服务端接口,包括项目初始化、配置、接口编写规范、数据库交互和多平台部署等完整流程。
本技能用于指导使用 Nitro v3 框架编写服务端接口,包括项目初始化、配置、接口编写规范、数据库交互和多平台部署等完整流程。
defineHandler)。ApiResponse 和 PageData 结构返回 { success, code, message, data }。类型定义参见 templates/types.ts。try-catch 包裹全部业务逻辑,catch 块返回标准化错误响应。# Nitro v3 核心包
pnpm add nitro
# 数据库相关(可选,推荐)
pnpm add drizzle-orm
pnpm add -D drizzle-kit
# 参数验证(可选,推荐)
pnpm add zod
# 日志工具(可选)
pnpm add consola
project-root/
├── server/ # Nitro 服务端目录
│ ├── routes/ # API 路由目录
│ │ ├── users.get.ts # GET /users
│ │ ├── users.post.ts # POST /users
│ │ └── health.get.ts # GET /health
│ ├── db/ # 数据库相关(可选)
│ │ ├── index.ts # 数据库连接(useDb)
│ │ └── schema/ # Drizzle Schema 定义
│ ├── utils/ # 工具函数
│ │ └── format-date.ts # 时间格式化(参见 templates/format-date.ts)
│ └── types/ # 类型定义
│ └── index.ts # ApiResponse、PageData 等(参见 templates/types.ts)
├── nitro.config.ts # Nitro 配置文件
└── package.json
project-root/
├── server/
│ ├── api/ # API 接口目录
│ │ └── {module}/{feature}/
│ │ ├── list.post.ts # 列表查询接口
│ │ ├── create.post.ts # 创建接口
│ │ ├── update.post.ts # 更新接口
│ │ ├── delete.post.ts # 删除接口
│ │ └── [id].get.ts # 详情接口
│ ├── db/ # 数据库连接和 Schema
│ └── utils/ # 工具函数
├── nitro.config.ts
└── package.json
文件路径映射规则:文件路径直接映射为 API 路径
文件: server/routes/users.get.ts -> GET /users
文件: server/api/users/list.post.ts -> POST /api/users/list
文件: server/api/users/[id].get.ts -> GET /api/users/:id
// ✅ 必须从 nitro/h3 导入,不是 h3
import { defineHandler, readBody } from "nitro/h3";
// ✅ 使用 defineHandler,不是 defineEventHandler
export default defineHandler(async (event) => {
// ...
});
仅 import type { ApiResponse } 是不够的——这只是一个死导入,TypeScript 不会检查返回值结构。
必须将 ApiResponse 用作响应变量的类型注解 (type annotation):
// ❌ 错误:仅导入类型,直接返回字面量 → TypeScript 不做任何检查
import type { ApiResponse } from "./types";
return { success: true, code: 200, msg: "ok", data: result }; // msg 拼错也不会报错
// ✅ 正确:用类型注解标注响应变量 → TypeScript 会严格检查每个字段
import type { ApiResponse } from "./types";
const response: ApiResponse<typeof result> = { success: true, code: 200, message: "ok", data: result };
return response; // 如果字段名/类型不符合 ApiResponse,编译期立即报错
| 端点类型 | 类型注解写法 |
|---|---|
| 分页列表(list) | ApiResponse<PageData<(typeof data)[number]>> |
| 单条数据(detail/create/update) | ApiResponse<typeof result> |
| 无数据返回(delete) | ApiResponse<null> |
| 错误响应(catch 块) | ApiResponse<null> |
(typeof data)[number]自动从 Drizzle 查询结果数组推断行类型,无需额外导入实体类型。
server/api/ 或 server/routes/ 创建文件。文件路径即 API 路由。defineHandler 定义处理函数,必须使用 try-catch 包裹。ApiResponse(列表接口额外导入 PageData)。db 与 schema,使用 Drizzle 查询构建器。ApiResponse<T> 结构。数据库 Schema 中的时间字段使用 Drizzle timestamp 类型,TypeScript 推断为 Date 类型。前端展示需要 string 类型。API Handler 负责时间字段的格式化转换。
必须使用共享的时间格式化工具函数(参见 templates/format-date.ts),禁止在 Handler 内重复定义格式化函数。
import { formatDateTime } from "server/utils/format-date"; // 根据你的项目结构调整
const list = data.map((item) => ({
id: item.id,
name: item.name,
createTime: formatDateTime(item.createTime),
updateTime: formatDateTime(item.updateTime),
}));
当 readValidatedBody 的类型推导不足以满足 Drizzle values() 的严格类型要求时,必须显式回填 Insert 类型。
// 从你的 Schema 文件导入 Insert 类型
import type { NewYourEntity } from "./schema";
const body = (await readValidatedBody(event, insertSchema.parse)) as unknown as NewYourEntity;
const result = await db.insert(table).values(body).returning();
本节基于 Cloudflare Worker 环境下排查真实严重 Bug 后沉淀的核心经验。
useDb(event) 获取数据库实例严禁在模块顶层或全局作用域直接创建 Drizzle 数据库连接实例:
// ❌ 错误:模块顶层创建,Cloudflare Worker 环境下 process.env 为空
const db = drizzle(neon(process.env.DATABASE_URL!));
// ✅ 正确:在每个 handler 内通过 event 动态获取
export default defineHandler(async (event) => {
const db = useDb(event); // 内部自动处理多平台环境变量
return await db.select().from(table);
});
在 Nitro v3 + Cloudflare Worker 环境中,event.context.cloudflare.env 不存在。
正确路径必须是 event.req.runtime?.cloudflare?.env(Nitro v3 官方确认路径)。
详细内容请参考:references/cloudflare-env-database.md
import { defineConfig } from "nitro";
export default defineConfig({
serverDir: "server",
imports: false,
compatibilityDate: "2024-09-19",
devServer: {
port: 3000,
},
});
// vite.config.ts
import { nitro } from "nitro/vite";
export default defineConfig({
plugins: [
// 其他插件...
nitro(),
],
});
import { defineConfig } from "nitro";
export default defineConfig({
serverDir: "server",
imports: false,
compatibilityDate: "2024-09-19",
cloudflare: {
deployConfig: true,
nodeCompat: true,
wrangler: {
name: "your-project-name",
},
},
// 如果使用 cloudflare:workers 动态导入
rollupConfig: {
external: ["cloudflare:workers"],
},
});
nitro/h3 导入,而非 h3。必须使用 defineHandler 而非 defineEventHandler。{ success, code, message, data } 结构。使用 msg 而非 message 会导致前端解析异常。try-catch 包裹,catch 块返回标准化错误响应。await。sql 模板字符串。请使用 Drizzle 的查询构建器。formatDateTime。event.req.runtime?.cloudflare?.env,而非 event.context.cloudflare?.env。| 错误写法 | 正确写法 |
|---|---|
import { defineEventHandler } from "h3" | import { defineHandler } from "nitro/h3" |
export default defineEventHandler(...) | export default defineHandler(...) |
| 直接返回对象无类型注解 | 使用 const response: ApiResponse<T> = ... |
process.env.DATABASE_URL(CF Worker) | event.req.runtime?.cloudflare?.env |
模块顶层 const db = drizzle(...) | handler 内 const db = useDb(event) |
nitro 依赖包server/routes/ 目录结构nitro.config.ts 配置文件package.jsonserver/types/ 并复制 templates/types.ts 中的类型定义nitro 依赖包nitro() 插件server/ 目录结构nitro.config.ts 配置文件server/types/ 并复制 templates/types.ts 中的类型定义drizzle-orm 和对应的数据库驱动drizzle-kit(开发依赖)server/db/index.ts(参考 references/cloudflare-env-database.md 中的 useDb 实现)server/db/schema/ 目录并定义数据表server/utils/详细的代码模板和参考文档请查阅:
ApiResponse<T>、PageData<T> 等通用类型定义,可直接复制使用formatDateTime、formatDate 工具函数readBody 使用、参数清洗和 Zod 校验npx claudepluginhub ruan-cat/monorepo --plugin dev-skillsGuides Nuxt 5 server-side development: API routes, middleware, Nitro v3/h3 v2 patterns, database integration (D1, Drizzle, PostgreSQL), and Nitro v2 migrations.
Develops Nuxt 4 server-side features with Nitro: API routes, server middleware, database integrations (D1, PostgreSQL, Drizzle), file uploads, WebSockets.
Creates REST API endpoints inside a Nuxt project using Nitro's event-handler model and H3 utilities. Handles file-based routing, request body parsing, query parameters, route params, error serialization, and custom response headers.