每位开发者都应遵循的后端设置
Source: Dev.to

介绍
在编写后端代码之前,拥有一个干净且组织良好的设置非常重要——它能帮助你更好地扩展、调试和协作。
它主要包括 6 个层次:
- 路由
- 控制器
- 中间件
- 服务
- 仓库
- 数据库
路由 – 入口点
路由定义了当特定请求到达服务器时应运行哪个函数。它们将 HTTP 方法和 URL 映射到控制器。
router.post("/signup", userController.signup);
router.get("/profile", authMiddleware, userController.getProfile);
路由应该保持简洁轻量。它们不包含业务逻辑;只决定请求的去向。可以把路由看作后端的路线图。
控制器 – 请求处理程序
控制器负责:
- 读取请求数据(
req.body、req.params、req.query) - 发送响应(
res.json、res.status) - 调用服务层
它们 不应:
- 包含业务逻辑
- 直接操作数据库
- 对密码进行哈希处理
- 计算业务规则
将控制器视作前台接待员:它们接收请求并作出响应。
中间件 – 看门人
中间件在控制器之前运行。它用于:
- 身份验证(JWT 验证)
- 日志记录
- 输入验证
- 限流
- 错误处理
router.get("/profile", authMiddleware, userController.getProfile);
请求必须先通过中间件才能到达控制器。可以把中间件想象成机场的安检。
Source: …
服务 – 应用程序的大脑
这里是实际业务逻辑所在。服务负责:
- 业务规则
- 数据转换
- 工作流决策
- 多个仓库的编排
exports.signup = async ({ email, password }) => {
const existingUser = await userRepository.findByEmail(email);
if (existingUser) {
throw new Error("User already exists");
}
const hashedPassword = await bcrypt.hash(password, 10);
return await userRepository.createUser(email, hashedPassword);
};
将服务视为决策者。
Repository – 数据访问层
The repository is responsible for:
- 与数据库通信
- 执行查询
- 返回原始数据
It does NOT:
- 决定业务规则
- 验证逻辑
exports.findByEmail = async (email) => {
return db("users").where({ email }).first();
};
Repository 是对数据库的抽象。如果你从 PostgreSQL 切换到 MongoDB,只需要更改 repository 层。把 repository 看作是你的应用与数据库之间的翻译器。
数据库 – 存储引擎
这是你的:
- PostgreSQL
- MySQL
- MongoDB
- Supabase
它的工作很简单:
- 存储数据
- 检索数据
- 维护完整性
它不关心 HTTP、业务逻辑或应用规则;它只负责存储信息。
完整请求流程
- 用户注册。
- 请求命中 Route。
- Middleware 验证 token/输入。
- Controller 接收请求。
- Controller 调用 Service。
- Service 应用业务逻辑。
- Service 调用 Repository。
- Repository 与 Database 交互。
- 响应沿链路返回。
Database → Repository → Service → Controller → Client
Clean. Predictable. Scalable.
🧠 简单思维模型
如果你对某个东西归属感到困惑,可以问:
- 它处理 HTTP 吗? → Controller
- 它进行验证/认证/日志记录吗? → Middleware
- 它是业务逻辑吗? → Service
- 它是数据库查询吗? → Repository
- 它是存储吗? → Database
- 它将端点映射到控制器吗? → Route