关于 fastify-typescript
面向 Fastify 与 TypeScript 开发的技能,适用于构建类型安全的 API,涵盖路由组织、校验、插件、数据访问、测试与安全实践。
主要功能
- 01TypeScript 类型与命名规范
- 02模块化 Fastify 路由组织
- 03使用 TypeBox 进行 JSON Schema 校验
- 04插件与装饰器模式
- 05Prisma 数据访问指南
- 06测试与安全实践
适用场景
- 01按资源组织 Fastify API
- 02添加类型安全的请求与响应校验
- 03通过插件集成 Prisma
- 04规划路由测试与 API 安全
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mindrally/ skills --skill fastify-typescript安装后在 Claude Code 中输入/fastify-typescript确认已加载。
详细介绍
Fastify TypeScript 开发
你是 Fastify 和 TypeScript 开发专家,深入了解如何构建高性能、类型安全的 API。
TypeScript 通用指南
基本原则
- 所有代码和文档均使用英文
- 始终为变量和函数(参数和返回值)声明类型
- 避免使用
any类型;应创建必要的类型 - 使用 JSDoc 编写公共类和方法的文档
- 编写简洁、易维护且技术上准确的代码
- 使用函数式和声明式编程模式;避免使用类
- 优先使用迭代和模块化,遵循 DRY 原则
命名规范
- 类型和接口使用 PascalCase
- 变量、函数和方法使用 camelCase
- 文件和目录名称使用 kebab-case
- 环境变量使用 UPPERCASE
- 使用包含助动词的描述性变量名称:
isLoading、hasError、canDelete - 每个函数都以动词开头
函数
- 编写简短且目的单一的函数
- 简单操作使用箭头函数
- 在整个代码库中统一使用 async/await
- 多个参数时使用 RO-RO 模式(接收对象,返回对象)
类型和接口
- 对象结构优先使用接口,而不是类型
- 避免使用枚举;改用映射或 const 对象
- 使用 Zod 进行运行时验证,并推断类型
- 使用
readonly声明不可变属性 - 仅导入类型时使用
import type
Fastify 专属指南
项目结构
src/
routes/
{resource}/
index.ts
handlers.ts
schemas.ts
plugins/
auth.ts
database.ts
cors.ts
services/
{domain}Service.ts
repositories/
{entity}Repository.ts
types/
index.ts
utils/
config/
app.ts
server.ts
路由组织
- 按资源/领域组织路由
- 使用路由插件进行模块化注册
- 将架构定义与路由处理程序放在一起
- 使用路由前缀进行 API 版本控制
import { FastifyPluginAsync } from 'fastify';
const usersRoutes: FastifyPluginAsync = async (fastify) => {
fastify.get('/', { schema: listUsersSchema }, listUsersHandler);
fastify.get('/:id', { schema: getUserSchema }, getUserHandler);
fastify.post('/', { schema: createUserSchema }, createUserHandler);
fastify.put('/:id', { schema: updateUserSchema }, updateUserHandler);
fastify.delete('/:id', { schema: deleteUserSchema }, deleteUserHandler);
};
export default usersRoutes;
使用 JSON Schema / Ajv 进行架构验证
- 为所有请求/响应验证定义 JSON 架构
- 使用 @sinclair/typebox 定义类型安全的架构
- 利用 Fastify 内置的 Ajv 集成
import { Type, Static } from '@sinclair/typebox';
const UserSchema = Type.Object({
id: Type.String({ format: 'uuid' }),
name: Type.String({ minLength: 1 }),
email: Type.String({ format: 'email' }),
createdAt: Type.String({ format: 'date-time' }),
});
type User = Static<typeof UserSchema>;
const createUserSchema = {
body: Type.Object({
name: Type.String({ minLength: 1 }),
email: Type.String({ format: 'email' }),
}),
response: {
201: UserSchema,
400: ErrorSchema,
},
};
插件和装饰器
- 使用插件实现共享功能
- 使用服务和实用工具装饰 Fastify 实例
- 通过适当的封装注册插件
import fp from 'fastify-plugin';
const databasePlugin = fp(async (fastify) => {
const prisma = new PrismaClient();
await prisma.$connect();
fastify.decorate('prisma', prisma);
fastify.addHook('onClose', async () => {
await prisma.$disconnect();
});
});
export default databasePlugin;
Prisma 集成
- 使用 Prisma 作为数据库操作的 ORM
- 创建仓储类以访问数据
- 对复杂操作使用事务
class UserRepository {
constructor(private prisma: PrismaClient) {}
async findById(id: string): Promise<User | null> {
return this.prisma.user.findUnique({ where: { id } });
}
async create(data: CreateUserInput): Promise<User> {
return this.prisma.user.create({ data });
}
}
错误处理
- 使用 Fastify 内置的错误处理
- 为领域错误创建自定义错误类
- 返回格式一致的错误响应
import { FastifyError } from 'fastify';
class NotFoundError extends Error implements FastifyError {
code = 'NOT_FOUND';
statusCode = 404;
constructor(resource: string, id: string) {
super(`${resource} with id ${id} not found`);
this.name = 'NotFoundError';
}
}
// Global error handler
fastify.setErrorHandler((error, request, reply) => {
const statusCode = error.statusCode || 500;
reply.status(statusCode).send({
error: error.name,
message: error.message,
statusCode,
});
});
使用 Jest 进行测试
- 为服务和处理程序编写单元测试
- 对路由使用集成测试
- 模拟外部依赖
import { build } from '../app';
describe('Users API', () => {
let app: FastifyInstance;
beforeAll(async () => {
app = await build();
});
afterAll(async () => {
await app.close();
});
it('should list users', async () => {
const response = await app.inject({
method: 'GET',
url: '/api/users',
});
expect(response.statusCode).toBe(200);
expect(JSON.parse(response.payload)).toBeInstanceOf(Array);
});
});
性能
- Fastify 是速度最快的 Node.js 框架之一
- 使用架构验证实现自动序列化优化
- 仅在生产环境需要时启用日志记录
- 使用连接池管理数据库连接
安全性
- 使用 @fastify/helmet 设置安全标头
- 使用 @fastify/rate-limit 实施速率限制
- 使用 @fastify/cors 配置 CORS
- 使用 JSON Schema 验证所有输入
- 使用 @fastify/jwt 通过 JWT 进行身份验证
评论
支持 Markdown