Express后端代码优化咨询:如何让代码更简洁专业且可复用?
Express路由与代码结构优化方案
针对你的代码,从模块化拆分、错误处理复用、数据库连接优化、路由规范几个维度给出具体优化建议:
1. 模块化拆分:分离职责模块
把不同功能的代码拆分到单独文件,提升可维护性:
config/db.js:数据库连接配置routes/tableRoutes.js:表相关路由逻辑utils/errorHandlers.js:通用错误处理函数
2. 修复代码低级错误
- 修正
DELETE语句中表名拼写错误(tabla改为table) - 修正
POST接口错误判断变量名(error改为err) - 移除重复的
app.all("/api/table", methodNotAllowed)注册,仅在对应HTTP方法定义完成后添加一次
3. 复用错误处理逻辑
把重复的错误响应逻辑抽成通用函数,避免代码冗余
4. 优化数据库连接
用连接池替代单连接(mysql2的createPool),提升性能与稳定性;添加连接失败的退出逻辑,避免服务静默启动失败
5. 使用Express Router组织路由
通过express.Router()管理同一前缀的路由,让代码结构更清晰
拆分后的具体代码示例
1. config/db.js - 数据库连接配置
const mysql2 = require('mysql2'); // 使用连接池替代单连接 const pool = mysql2.createPool({ host: "localhost", user: "root", password: "", database: "dbname", waitForConnections: true, connectionLimit: 10, queueLimit: 0 }); // 测试连接并处理失败情况 pool.getConnection((err, conn) => { if (err) { console.error('数据库连接失败:', err.message); process.exit(1); // 连接失败直接退出服务 } console.log('数据库连接成功!'); conn.release(); }); module.exports = pool;
2. utils/errorHandlers.js - 通用错误处理
// 405方法不允许响应 exports.methodNotAllowed = (req, res) => { res.status(405).json({ message: "Method not allowed!" }); }; // 通用数据库错误响应 exports.dbErrorHandler = (res, err, message = "数据库操作失败") => { console.error('数据库错误:', err); return res.status(500).json({ message }); }; // 参数校验错误响应 exports.validationError = (res, message = "参数缺失或格式错误") => { return res.status(400).json({ message }); };
3. routes/tableRoutes.js - 表路由逻辑
const express = require('express'); const router = express.Router(); const pool = require('../config/db'); const { methodNotAllowed, dbErrorHandler, validationError } = require('../utils/errorHandlers'); // 获取所有数据 router.get('/', (req, res) => { const sql = "SELECT * FROM `table`"; // table是SQL关键字,用反引号包裹避免语法错误 pool.query(sql, (err, result) => { if (err) return dbErrorHandler(res, err); res.status(200).json(result); }); }); // 新增数据 router.post('/', (req, res) => { const { name } = req.body; if (!name) return validationError(res, "缺少name参数"); const sql = "INSERT INTO `table` (name) VALUES (?)"; pool.query(sql, [name], (err, result) => { if (err) return dbErrorHandler(res, err); res.status(201).json({ id: result.insertId }); }); }); // 删除数据 router.delete('/:id', (req, res) => { const { id } = req.params; const sql = "DELETE FROM `table` WHERE id = ?"; pool.query(sql, [id], (err, result) => { if (err) return dbErrorHandler(res, err); res.status(200).json({ message: "删除成功!" }); }); }); // 更新数据 router.put('/:id', (req, res) => { const { id } = req.params; const { name } = req.body; if (!name) return validationError(res, "缺少name参数"); const sql = "UPDATE `table` SET name = ? WHERE id = ?"; pool.query(sql, [name, id], (err, result) => { if (err) return dbErrorHandler(res, err); res.status(200).json({ message: "更新成功!" }); }); }); // 处理未定义的请求方法 router.all('/', methodNotAllowed); router.all('/:id', methodNotAllowed); module.exports = router;
4. 主文件server.js
const express = require('express'); const cors = require('cors'); const tableRoutes = require('./routes/tableRoutes'); const app = express(); const PORT = 3000; // 全局中间件 app.use(express.json()); app.use(cors()); // 挂载路由 app.use('/api/table', tableRoutes); // 启动服务 app.listen(PORT, () => { console.log(`服务运行在 http://localhost:${PORT}`); });
额外专业性建议
- SQL关键字处理:
table是SQL保留关键字,操作时用反引号`包裹,避免语法错误 - 环境变量配置:将数据库密码、端口等敏感信息存入
.env文件,用dotenv包读取,避免硬编码 - 参数校验增强:使用
joi或express-validator实现更严谨的请求参数校验 - 日志记录:用
winston或morgan记录请求与错误日志,便于问题排查 - 异步语法改造:将回调式的
db.query转为Promise风格,用async/await提升代码可读性(mysql2支持promise()方法)
内容的提问来源于stack exchange,提问作者skynet007
相关产品推荐
相关产品推荐

