Vafast 教程
我们将构建一个简单的 CRUD 笔记 API 服务器。
这里没有数据库,也没有其他"生产就绪"功能。本教程将重点介绍 Vafast 的功能以及如何仅使用 Vafast。
如果你跟着做,我们预计大约需要 15-20 分钟。
来自其他框架?
如果您使用过其他流行框架,如 Express、Fastify 或 Hono,您会发现 Vafast 非常熟悉,只是有一些小差异。
不喜欢教程?
如果您更倾向于自己动手的方式,可以跳过这个教程,直接访问 关键概念 页面,深入了解 Vafast 的工作原理。
llms.txt
或者,您可以下载 llms.txt 或 llms-full.txt,并将其输入您最喜欢的 LLM,如 ChatGPT、Claude 或 Gemini,以获得更互动的体验。
设置
Vafast 的设计是运行在 Bun 上,这是一个替代 Node.js 的运行时,但它也可以运行在 Node.js 或任何支持 Web 标准 API 的运行时上。
然而,在本教程中,我们将使用 Bun。
如果您还没有安装 Bun,请先安装。
bash
curl -fsSL https://bun.sh/install | bashbash
powershell -c "irm bun.sh/install.ps1 | iex"创建一个新项目
bash
# 创建一个新目录
mkdir hi-vafast
cd hi-vafast
# 初始化项目
bun init
# 安装 Vafast
bun add vafast
bun add -d @types/bun项目结构
创建项目后,您应该看到以下结构:
hi-vafast/
├── src/
│ └── index.ts
├── package.json
├── tsconfig.json
└── README.md启动开发服务器
bash
bun run --hot src/index.ts现在您应该能够在 http://localhost:3000 看到 "Hello Vafast!" 消息。
构建笔记 API
现在让我们开始构建我们的笔记 API。我们将创建一个简单的内存存储系统来管理笔记。
1. 定义笔记类型
首先,让我们在 src/index.ts 中定义我们的笔记类型:
typescript
interface Note {
id: string
title: string
content: string
createdAt: Date
updatedAt: Date
}
// 内存存储
const notes: Note[] = []2. 创建路由
现在让我们创建我们的 API 路由:
typescript
import { Server, defineRoutes, createHandler } from 'vafast'
const routes = defineRoutes([
// 获取所有笔记
{
method: 'GET',
path: '/notes',
handler: createHandler(() => {
return notes
})
},
// 获取单个笔记
{
method: 'GET',
path: '/notes/:id',
handler: createHandler(({ params }) => {
const id = params.id
const note = notes.find(n => n.id === id)
if (!note) {
return new Response('Note not found', { status: 404 })
}
return note
})
},
// 创建笔记
{
method: 'POST',
path: '/notes',
handler: createHandler(async ({ req }) => {
const body = await req.json()
const { title, content } = body
if (!title || !content) {
return new Response('Title and content are required', { status: 400 })
}
const note: Note = {
id: Date.now().toString(),
title,
content,
createdAt: new Date(),
updatedAt: new Date()
}
notes.push(note)
return note
})
},
// 更新笔记
{
method: 'PUT',
path: '/notes/:id',
handler: createHandler(async ({ req, params }) => {
const id = params.id
const noteIndex = notes.findIndex(n => n.id === id)
if (noteIndex === -1) {
return new Response('Note not found', { status: 404 })
}
const body = await req.json()
const { title, content } = body
if (!title || !content) {
return new Response('Title and content are required', { status: 400 })
}
notes[noteIndex] = {
...notes[noteIndex],
title,
content,
updatedAt: new Date()
}
return notes[noteIndex]
})
},
// 删除笔记
{
method: 'DELETE',
path: '/notes/:id',
handler: createHandler(({ params }) => {
const id = params.id
const noteIndex = notes.findIndex(n => n.id === id)
if (noteIndex === -1) {
return new Response('Note not found', { status: 404 })
}
const deletedNote = notes.splice(noteIndex, 1)[0]
return deletedNote
})
}
])
const server = new Server(routes)
export default { fetch: server.fetch }3. 测试 API
现在让我们测试我们的 API。重启开发服务器:
bash
bun run --hot src/index.ts创建笔记
bash
curl -X POST http://localhost:3000/notes \
-H "Content-Type: application/json" \
-d '{"title": "我的第一个笔记", "content": "这是笔记的内容"}'获取所有笔记
bash
curl http://localhost:3000/notes获取单个笔记
bash
curl http://localhost:3000/notes/1234567890更新笔记
bash
curl -X PUT http://localhost:3000/notes/1234567890 \
-H "Content-Type: application/json" \
-d '{"title": "更新的标题", "content": "更新的内容"}'删除笔记
bash
curl -X DELETE http://localhost:3000/notes/1234567890添加中间件
让我们为我们的 API 添加一些中间件来增强功能:
1. 日志中间件
typescript
const logMiddleware = async (req: Request, next: () => Promise<Response>) => {
const start = Date.now()
console.log(`${new Date().toISOString()} - ${req.method} ${req.url}`)
const response = await next()
const duration = Date.now() - start
console.log(`Response: ${response.status} (${duration}ms)`)
return response
}2. 错误处理中间件
typescript
const errorHandler = async (req: Request, next: () => Promise<Response>) => {
try {
return await next()
} catch (error) {
console.error('Error:', error)
return new Response(
JSON.stringify({
error: 'Internal Server Error',
message: error.message
}),
{
status: 500,
headers: { 'Content-Type': 'application/json' }
}
)
}
}3. 使用中间件
typescript
const routes = defineRoutes([
{
method: 'GET',
path: '/notes',
middleware: [logMiddleware, errorHandler],
handler: createHandler(() => {
return notes
})
}
// ... 其他路由
])添加验证
让我们为我们的 API 添加一些基本的验证。Vafast 集成了 TypeBox 进行 Schema 验证:
typescript
import { Type } from '@sinclair/typebox'
const noteSchema = Type.Object({
title: Type.String({ minLength: 1, maxLength: 100 }),
content: Type.String({ minLength: 1, maxLength: 1000 })
})
const routes = defineRoutes([
{
method: 'POST',
path: '/notes',
handler: createHandler(async ({ req, body }) => {
// body 已经通过验证,类型安全
const { title, content } = body
const note: Note = {
id: Date.now().toString(),
title,
content,
createdAt: new Date(),
updatedAt: new Date()
}
notes.push(note)
return note
}),
body: noteSchema
}
])总结
恭喜!您已经成功构建了一个完整的 CRUD API 服务器,包括:
- ✅ 创建、读取、更新和删除笔记
- ✅ 中间件支持(日志记录、错误处理)
- ✅ Schema 验证
- ✅ 类型安全的 TypeScript 代码
- ✅ 内存数据存储
下一步
现在您可以:
- 添加更多功能 - 如搜索、分页、排序等
- 集成数据库 - 如 SQLite、PostgreSQL 或 MongoDB
- 添加身份验证 - 用户登录和权限控制
- 部署到生产环境 - 如 Vercel、Netlify 或自己的服务器
