从零搭建 Express + Sequelize + MySQL 全栈 API 项目(含 Docker 部署)
本文将手把手带你使用Express搭建一个支持增删改查CRUD的后端 API 项目集成SequelizeORM 操作 MySQL 数据库并通过Docker Desktop容器化运行。涵盖项目初始化、热更新配置、数据库迁移、种子数据填充及完整 RESTful 接口实现。一、创建 Express 项目1. 全局安装 express-generatornpm install express-generator -g2. 创建无视图模板的项目express --no-view clwy-api cd clwy-api npm install也可以分步执行express --no-view clwy-api cd clwy-api npm install3. 启动项目npm start运行成功后访问 http://localhost:3000/二、使用 Nodemon 实现热更新每次修改代码都要手动重启用nodemon自动监听文件变化并重启1. 全局安装 nodemonnpm install nodemon -g2. 修改package.json将scripts.start改为使用nodemon{ name: clwy-api, version: 0.0.0, private: true, scripts: { start: nodemon ./bin/www }, dependencies: { cookie-parser: ~1.4.4, debug: ~2.6.9, express: ~4.16.1, morgan: ~1.9.1 } }三、使用 Docker Desktop 运行 MySQL1. 下载并安装 Docker Desktop官网地址https://www.docker.com/products/docker-desktop/Windows 用户选择AMD64版本安装完成后启动应用2. 启动 MySQL 容器示例docker-compose.ymlversion: 3.8 services: mysql: image: mysql:8.3.0 command: --default-authentication-pluginmysql_native_password environment: - MYSQL_ROOT_PASSWORDclwy1234 ports: - 13306:3306在项目根目录运行docker compose up -d注意这里将容器的3306映射到宿主机的13306后续连接需使用13306端口。四、集成 Sequelize 操作数据库1. 安装依赖# 全局安装 CLI 工具 npm install -g sequelize-cli # 本地安装核心库 npm install sequelize mysql2 Sequelize 中文文档https://www.sequelize.cn/2. 初始化 Sequelize 项目sequelize init生成以下目录结构对应项目中的文件位置config/config.json项目的配置文件里面存放着不同环境下development-开发环境、test-测试环境、production-生产环境的数据库的配置信息比如数据库的连接地址、用户名、密码、数据库名等等需要把对应的配置信息填写进去。migrations文件夹存放着数据库迁移文件比如创建数据库表、添加字段等等。models文件夹存放着数据库模型文件比如定义数据库表结构、字段类型、字段约束等等。seeders文件夹存放着数据填充文件比如初始化数据库数据等等3. 配置数据库连接编辑config/config.json填入你的 MySQL 信息以开发环境为例{ development: { username: root, password: clwy1234, database: clwy, host: 127.0.0.1, port: 13306, dialect: mysql } }port必须与 Docker 映射的宿主机端口一致这里是13306。五、创建模型、迁移与种子数据1. 生成 Articles 模型sequelize model:generate --name Articles --attributes title:string,content:text生成models/articles.js生成migrations/时间戳-create-articles.js2. 执行数据库迁移sequelize db:migrate此时数据库会自动创建articles表。3. 生成并填充测试数据(1) 生成种子文件sequelize seed:generate --name articles✅ 生成seeders/时间戳-articles.js(2) 修改种子文件插入 100 条测试数据// seeders/20260313120000-articles.js module.exports { up: async (queryInterface, Sequelize) { const articles []; for (let i 1; i 100; i) { articles.push({ title: 新闻标题 ${i}, content: 这是第 ${i} 条新闻的详细内容..., createdAt: new Date(), updatedAt: new Date() }); } await queryInterface.bulkInsert(Articles, articles, {}); }, down: async (queryInterface, Sequelize) { await queryInterface.bulkDelete(Articles, null, {}); } };(3) 执行种子填充sequelize db:seed --seed 20260313120000-articles✅ 成功插入 100 条数据六、实现 CRUD 接口1. 查询所有文章在routes/admin/articles.js中添加const express require(express); const router express.Router(); const { Articles } require(../../models); /* GET /admin/articles - 查询所有文章 */ router.get(/, async (req, res) { try { const articles await Articles.findAll({ order: [[id, DESC]] }); res.json({ status: true, data: { articles }, message: 查询成功 }); } catch (error) { res.status(500).json({ status: false, message: error.message }); } });在app.js中注册路由const adminArticlesRouter require(./routes/admin/articles); app.use(/admin/articles, adminArticlesRouter);✅ 测试接口GET http://localhost:3000/admin/articles2. 查询文章详情/* GET /admin/articles/:id - 查询文章详情 */ router.get(/:id, async (req, res) { try { const { id } req.params; if (!id) return res.status(400).json({ status: false, message: id不能为空 }); const article await Articles.findByPk(id); if (!article) return res.status(404).json({ status: false, message: 文章不存在 }); res.json({ status: true, data: { data: article }, message: 查询成功 }); } catch (error) { res.status(500).json({ status: false, message: error.message }); } });✅ 测试GET http://localhost:3000/admin/articles/13. 创建文章/* POST /admin/articles - 创建文章 */ router.post(/, async (req, res) { try { const { title, content } req.body; if (!title) return res.status(400).json({ status: false, message: 标题不能为空 }); const result await Articles.create({ title, content }); res.json({ status: true, data: { data: result }, message: 创建成功 }); } catch (error) { res.status(500).json({ status: false, message: error.message }); } });✅ 测试POST http://localhost:3000/admin/articlesBody: JSON4. 修改文章/* PUT /admin/articles - 修改文章 */ router.put(/, async (req, res) { try { const { id, title, content } req.body; if (!id || !title) return res.status(400).json({ status: false, message: 参数错误 }); const [updated] await Articles.update({ title, content }, { where: { id } }); if (updated 0) return res.status(404).json({ status: false, message: 文章未找到 }); res.json({ status: true, message: 修改成功 }); } catch (error) { res.status(500).json({ status: false, message: error.message }); } });✅ 测试PUT http://localhost:3000/admin/articles5. 删除文章/* DELETE /admin/articles/:id - 删除文章 */ router.delete(/:id, async (req, res) { try { const { id } req.params; if (!id) return res.status(400).json({ status: false, message: id不能为空 }); const deleted await Articles.destroy({ where: { id } }); if (deleted 0) return res.status(404).json({ status: false, message: 文章不存在 }); res.json({ status: true, message: 删除成功 }); } catch (error) { res.status(500).json({ status: false, message: error.message }); } });✅ 测试DELETE http://localhost:3000/admin/articles/1
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2409477.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!