fastify-typescript by mindrally/skills
npx skills add https://github.com/mindrally/skills --skill fastify-typescript您是一位精通 Fastify 和 TypeScript 开发的专家,深谙构建高性能、类型安全 API 的知识。
any 类型 - 应创建必要的类型isLoading、hasError、canDelete广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
readonlyimport typesrc/
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 模式
使用 @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 作为数据库操作的 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';
}
}
// 全局错误处理器 fastify.setErrorHandler((error, request, reply) => { const statusCode = error.statusCode || 500;
reply.status(statusCode).send({ error: error.name, message: error.message, statusCode, }); });
为服务和处理器编写单元测试
对路由使用集成测试
模拟外部依赖
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);
}); });
每周安装量
135
代码仓库
GitHub 星标数
42
首次出现时间
2026年1月25日
安全审计
安装于
gemini-cli114
opencode112
codex109
cursor107
github-copilot106
amp94
You are an expert in Fastify and TypeScript development with deep knowledge of building high-performance, type-safe APIs.
any type - create necessary types insteadisLoading, hasError, canDeletereadonly for immutable propertiesimport type for type-only importssrc/
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
Organize routes by resource/domain
Use route plugins for modular registration
Define schemas alongside route handlers
Use route prefixes for API versioning
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;
Define JSON schemas for all request/response validation
Use @sinclair/typebox for type-safe schema definitions
Leverage Fastify's built-in Ajv integration
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, }, };
Use plugins for shared functionality
Decorate Fastify instance with services and utilities
Register plugins with proper encapsulation
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;
Use Prisma as the ORM for database operations
Create repository classes for data access
Use transactions for complex operations
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 }); } }
Use Fastify's built-in error handling
Create custom error classes for domain errors
Return consistent error responses
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, }); });
Write unit tests for services and handlers
Use integration tests for routes
Mock external dependencies
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);
}); });
Weekly Installs
135
Repository
GitHub Stars
42
First Seen
Jan 25, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
gemini-cli114
opencode112
codex109
cursor107
github-copilot106
amp94
lark-cli 共享规则:飞书资源操作指南与权限配置详解
39,000 周安装