fastify框架MVC架构教程

3 min read
Fastify 标准项目结构示例
project-root/
├── src/ # 源代码目录
│ ├── controllers/ # 路由逻辑(处理请求的控制器)
│ │ └── user.controller.ts
│ ├── services/ # 业务逻辑层
│ │ └── user.service.ts
│ ├── routes/ # 路由定义
│ │ └── user.route.ts
│ ├── schemas/ # JSON Schema 定义(用于请求/响应验证)
│ │ └── user.schema.ts
│ ├── plugins/ # Fastify 插件(自定义功能)
│ │ └── db.plugin.ts
│ ├── config/ # 配置文件
│ │ └── database.ts
│ ├── types/ # TypeScript 类型定义
│ │ └── index.ts
│ └── app.ts # Fastify 应用主入口
├── tests/ # 测试目录
│ └── user.test.ts
├── .env # 环境变量文件
├── .gitignore # Git 忽略文件
├── package.json # 项目依赖和脚本
├── tsconfig.json # TypeScript 配置文件
└── README.md # 项目说明
各部分详细说明
1.src/app.ts - 应用主入口
这是 Fastify 实例的初始化文件,负责启动服务器、注册插件和路由。
import fastify, { FastifyInstance } from 'fastify';
import dbPlugin from './plugins/db.plugin';
import userRoutes from './routes/user.route';
const app: FastifyInstance = fastify({ logger: true });
// 注册插件
app.register(dbPlugin);
// 注册路由(带前缀)
app.register(userRoutes, { prefix: '/api/users' });
const start = async () => {
try {
await app.listen({ port: 3000 });
console.log('Server running on http://localhost:3000');
} catch (err) {
app.log.error(err);
process.exit(1);
}
};
start();
2. src/routes/ - 路由定义
路由文件负责定义 API 端点,通常与 Schema 结合使用。
// src/routes/user.route.ts
import { FastifyPluginAsync } from 'fastify';
import * as userSchema from '../schemas/user.schema';
import * as userController from '../controllers/user.controller';
const userRoutes: FastifyPluginAsync = async (fastify) => {
fastify.get(
'/',
{ schema: userSchema.getUsersSchema },
userController.getUsers
);
fastify.post(
'/',
{ schema: userSchema.createUserSchema },
userController.createUser
);
};
export default userRoutes;
3. src/schemas/ - JSON Schema 定义
Fastify 的一个亮点是内置对 JSON Schema 的支持,用于验证请求和响应。
// src/schemas/user.schema.ts
export const getUsersSchema = {
response: {
200: {
type: 'array',
items: {
type: 'object',
properties: {
id: { type: 'number' },
name: { type: 'string' },
},
},
},
},
};
export const createUserSchema = {
body: {
type: 'object',
required: ['name'],
properties: {
name: { type: 'string' },
},
},
response: {
201: {
type: 'object',
properties: {
id: { type: 'number' },
name: { type: 'string' },
},
},
},
};
4. src/controllers/ - 控制器
控制器处理具体的请求逻辑,通常调用服务层。
// src/controllers/user.controller.ts
import { FastifyRequest, FastifyReply } from 'fastify';
import * as userService from '../services/user.service';
export const getUsers = async (request: FastifyRequest, reply: FastifyReply) => {
const users = await userService.getAllUsers();
reply.send(users);
};
export const createUser = async (
request: FastifyRequest<{ Body: { name: string } }>,
reply: FastifyReply
) => {
const { name } = request.body;
const newUser = await userService.createUser(name);
reply.code(201).send(newUser);
};
5. src/services/ - 业务逻辑
服务层封装具体的业务逻辑,与数据层交互。
// src/services/user.service.ts
export const getAllUsers = async () => {
// 假设从数据库获取
return [{ id: 1, name: 'Alice' }, { id: 2, name: 'Bob' }];
};
export const createUser = async (name: string) => {
// 假设保存到数据库
return { id: 3, name };
};
6. src/plugins/ - 插件
Fastify 的插件系统允许封装可复用功能,比如数据库连接。
// src/plugins/db.plugin.ts
import { FastifyPluginAsync } from 'fastify';
import fp from 'fastify-plugin';
const dbPlugin: FastifyPluginAsync = async (fastify) => {
// 模拟数据库连接
const db = { connected: true };
fastify.decorate('db', db);
};
export default fp(dbPlugin);
7. src/config/ - 配置文件
存放配置项,比如数据库连接信息。
// src/config/database.ts
export const dbConfig = {
host: process.env.DB_HOST || 'localhost',
port: Number(process.env.DB_PORT) || 5432,
};
8. src/types/ - 类型定义
为 TypeScript 项目提供自定义类型。
// src/types/index.ts
import { FastifyInstance } from 'fastify';
declare module 'fastify' {
interface FastifyInstance {
db: { connected: boolean };
}
}
9. tests/ - 测试文件
用于单元测试或集成测试。
// tests/user.test.ts
import { test } from 'tap';
import { build } from '../src/app';
test('GET /api/users should return users', async (t) => {
const app = build();
const response = await app.inject({
method: 'GET',
url: '/api/users',
});
t.equal(response.statusCode, 200);
t.end();
});
为什么这样组织?
模块化: 路由、控制器、服务分离,便于维护和扩展。
验证优先: Schema 文件利用 Fastify 的验证功能,确保数据一致性。
插件驱动: 通过插件封装功能(如数据库连接),提高复用性。
测试友好: 结构清晰,易于编写单元测试和集成测试。
如何开始?
初始化项目
npm init -y npm install fastify typescript @types/node ts-node
配置 tsconfig.json:
{ "compilerOptions": { "target": "es2019", "module": "commonjs", "outDir": "./dist", "rootDir": "./src", "strict": true, "esModuleInterop": true } }
启动脚本(package.json):
{ "scripts": { "start": "ts-node src/app.ts", "build": "tsc", "test": "tap tests/*.ts" } }
0
Subscribe to my newsletter
Read articles from kimlopez directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
