node基于express+mongodb项目的整体结构搭建和逻辑抽离

一、为什么需要逻辑抽离

这是我用express实现的一个缩减版的注册功能,如下:

  • app.js
const express = require("express");
const app = express();// 连接数据库
const mongoose = require("mongoose");
// 连接数据库myTest
mongoose.connect("mongodb://localhost:27017/myTest", { useNewUrlParser: true, useUnifiedTopology: true }).then(() => {console.log("数据库连接成功");}).catch((err) => {console.log(err, "数据库连接失败");});
// 创建集合规则
const userSchema = new mongoose.Schema({userName: {type: String,required: true,},passWord: {type: String,required: true,},
});
// 创建Users集合
const User = mongoose.model("User", userSchema);const cors = require("cors");
// 解决跨域
app.use(cors());// 支持json格式的请求体数据
app.use(express.json());
// 支持urlencoded格式的请求体数据
app.use(express.urlencoded({ extended: true }));
// 注册接口
app.post("/register", async (req, res) => {const userModel = new User(req.body);// 将用户注册的信息保存到数据库中const dbBack = await userModel.save();user = dbBack.toJSON();// 以json格式返回给客户端res.status(201).json({code: 201,msg: "注册成功",user,});
});// 监听3000端口
app.listen(3000, () => {console.log("server is running at http://localhost:3000");
});

目录结构如下:
在这里插入图片描述

可以看到的是所有的逻辑,创建服务器、链接数据库、创建集合、注册都在app.js文件中,这只是一个简单的注册功能,可能看上去还不是很乱,但是当我们后面项目越来越大,所做的功能越来越多,显然,将所有的逻辑功能都集中在app.js中是不行的,这样既不利用开发,也不利于后期维护,所以对逻辑的抽离,和整体项目结构的划分是很有必要的。

二、项目结构的搭建

1. 路由模块的抽离

这里我们先不考虑注册功能是否能实现了,只是单纯的做个逻辑划分,看抽离完成之后的路由是否在客户端可以访问到就可以了。

新建router文件夹,在router文件夹下新建index.jsuser.js文件,如图:
在这里插入图片描述

  • index.js
const express = require('express');
const router = express.Router();
router.use('/user', require('./user'));
module.exports = router;
  • user.js
const express = require("express");
const router = express.Router();
router.post("/register", (req, res) => {console.log(req.body);  res.send("register");   
});
module.exports = router;

然后我们去app.js中引入router/index.js

  • app.js
const express = require("express");
const app = express();app.use(express.json());
const router = require("./router");
app.use('/api/v1', router);// 监听3000端口
app.listen(3000, () => {console.log("server is running at http://localhost:3000");
});

经过这样的抽离以后我们再访问user/register接口,就需要加上/api/v1前缀,如图:
在这里插入图片描述
到这里,我们看app.js文件中的代码逻辑是不是很清晰了,我们只是用express创建了一个web服务器,然后引入了一个路由文件,就实现了接口访问的逻辑。

那么接着看看user.js文件
在这里插入图片描述
这里的注册逻辑,我没有具体实现,但是后期我们实现的时候,这里逻辑肯定比这复杂,还有就是,user模块,肯定也不止这一个注册功能,比如还有登录、修改密码、修改头像等等,这时如果还是将接口的具体实现都集中在user.js中,最后的这个效果就和我们开始分析的app.js文件一养,逻辑太过复杂,导致user.js文件太过臃肿,不利于维护,所以,我们将user.js文件中的接口具体实现也单独抽离出来

新建一个controller文件夹,controller文件夹下新增一个userController.js文件

  • userController.js
// 用户注册
exports.register =(req, res) => {console.log(req.body);  res.send("register");   
}

修改user.js文件

const express = require("express");
const router = express.Router();
const userController = require("../controller/userController");
router.post("/register", userController.register);
module.exports = router;

这样比如我们要加个登录的功能,只需要在user中加一行代码就可以了,例如:

const express = require("express");
const router = express.Router();
const userController = require("../controller/userController");
router.post("/register", userController.register);
router.post("/login", userController.login);
module.exports = router;

而具体的登录逻辑,我们可以在userController中实现。
好啦,到这里我们的路由的抽离基本就可以了,接下来我们来具体实现一下开始的在app.js中的那个注册功能。

2. 数据库操作部分抽离

基于上面的路由抽离,要实现注册功能,我们可以在userController中来加上数据方面的操作,如下:

  • userController.js
// 连接数据库
const mongoose = require("mongoose");
// 连接数据库myTest
mongoose.connect("mongodb://localhost:27017/myTest", { useNewUrlParser: true, useUnifiedTopology: true }).then(() => {console.log("数据库连接成功");}).catch((err) => {console.log(err, "数据库连接失败");});
// 创建集合规则
const userSchema = new mongoose.Schema({userName: {type: String,required: true,},passWord: {type: String,required: true,},
});
// 创建Users集合
const User = mongoose.model("User", userSchema);// 用户注册
exports.register = async (req, res) => {const userModel = new User(req.body);// 将用户注册的信息保存到数据库中const dbBack = await userModel.save();user = dbBack.toJSON();// 以json格式返回给客户端res.status(201).json({code: 201,msg: "注册成功",user,});
};

此时我们在访问注册接口:
在这里插入图片描述
在这里插入图片描述
可以看到数据库users集合中成功添加了一条数据,说明我们的注册功能是实现了。但是,我们在回头看看userController.js,此时的数据库连接操作,创建集合都集中在了这里,就算我们创建users集合放在userController.js中合理,但是数据库连接呢?

我们的整个项目肯定不止涉及一个集合,每当新建个controller时,我们都要连接数据库,所以这个连接数据库的操作显然是一个可复用的功能,所以我们先把这一块的逻辑抽离出来。

新建一个model/index.js文件

  • model/index.js
const mongoose = require("mongoose");
mongoose.connect("mongodb://localhost:27017/myTest").then((res) => {console.log("mongo链接成功");}).catch((err) => {console.log(err);console.log("mongo链接失败");});module.exports = mongoose;

修改userController.js

const mongoose = require("../model/index");
// 创建集合规则
const userSchema = new mongoose.Schema({userName: {type: String,required: true,},passWord: {type: String,required: true,},
});
// 创建Users集合
const User = mongoose.model("User", userSchema);// 用户注册
exports.register = async (req, res) => {const userModel = new User(req.body);// 将用户注册的信息保存到数据库中const dbBack = await userModel.save();user = dbBack.toJSON();// 以json格式返回给客户端res.status(201).json({code: 201,msg: "注册成功",user,});
};

但是我们的userController中应该只注重接口的的具体实现,集合的规则和创建也应该单独抽离出来
新建model/userModel.js

  • model/userModel.js
const mongoose = require("mongoose");
// 创建集合规则
const userSchema = new mongoose.Schema({userName: {type: String,required: true,},passWord: {type: String,required: true,},
});module.exports = userSchema;

修改model/index导出

  • model/index.js
const mongoose = require("mongoose");
const { mongopath } = require("../config/config.default");
mongoose.connect(mongopath).then((res) => {console.log("mongo链接成功");}).catch((err) => {console.log(err);console.log("mongo链接失败");});module.exports = {User: mongoose.model("User", require("./userModel")),
};

修改userController.js

  • userController.js
const { User } = require("../model/index");// 用户注册
exports.register = async (req, res) => {const userModel = new User(req.body);// 将用户注册的信息保存到数据库中const dbBack = await userModel.save();user = dbBack.toJSON();// 以json格式返回给客户端res.status(201).json({code: 201,msg: "注册成功",user,});
};

至此我们实现了controller功能的单一性,也将数据操作都抽离到了model文件夹下,这时我们在用postman访问一下register接口,如下:
在这里插入图片描述
在这里插入图片描述
成功访问!

至此呢我们项目的基本架构就算完成啦。
整体目录结构如下:
在这里插入图片描述
将路由相关访问抽离到router文件夹下,接口逻辑的具体实现抽离到controller文件夹下,数据库集合相关操作抽离到model文件夹下,一些配置文件抽离到config文件夹下,我们的入口文件app.js只是创建一个服务器,具体的功能我们只需要引入对于的模块就可以了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/22246.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Stable Diffusion - After Detailer 插件 脸部和手部 重绘算法与应用

欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://spike.blog.csdn.net/article/details/131699857 After Detailer 是一个用于 Stable Diffusion Webui 的扩展插件,可以自动检测、遮盖和修复图片中的人脸、手部或全身&#…

Java 的集合

一、Collection 1、ArrayList 底层采用数组实现,操作大多基于对数组的操作。 在添加和删除时需要做 System.arraycopy(native层方法) 拷贝工作。 添加元素时可能会扩容,这要大量的拷贝工作,删除元素时,会把后面的元素向前拷贝。…

【NLP】Transformer模型原理(2)

接上文 【NLP】Transformer模型原理(1) 六、零层的transformer 观看涵盖与本节类似内容的视频:0 层理论 在进入更复杂的模型之前,简要考虑一下“零层”变压器很有用。这样的模型获取一个令牌,嵌入它,解嵌它以生成预测下一个令牌的对数: ​

Ext4文件系统介绍 - 实战篇

本文主要通过dd,hexdump和dumpe2fs工具分析ext4的磁盘二进制数据,加深对ext4文件系统的印象,要想理解本建议先阅读下Ext4文件系统介绍 - 理论篇_nginux的博客-CSDN博客。 磁盘超级块数据分析 根据理论篇我们知道ext4 layout中前1024字节是x…

抖音seo源码矩阵系统开发规则开发者分享(一)

抖音SEO矩阵系统源码开发,需要遵循一下步骤 1. 确定需求和功能:明确系统的主要目标和需要实现的功能,包括关键词研究、短视频制作、外链建设、数据分析、账号设置优化等方面。 2. 设计系统架构:根据需求和功能确定系统的架构&am…

数据结构--绪论

这里写目录标题 前言数据结构研究内容基本概念与术语数据元素与数据对象的区别数据结构逻辑结构存储结构 数据类型和抽象数据类型数据类型抽象数据类型定义格式举例 小结研究内容基础概念 抽象数据类型的表示和实现 算法与分析算法的设计要求算法效率事前分析法例子 算法时间的…

【导航地图DB-kiwi地图格式】

背景知识: kiwi趣闻: kiwi是新西兰的一种鸟的名称,Kiwi鸟是尾巴翅膀极短不会飞的鸟,非常珍贵,只在新西兰僻静的丛林里才能见到,所以成为新西兰的国鸟。Kiwi鸟…

【iOS内存管理-内存的几大区域】

前言 iOS内存管理的第一篇章,了解iOS内存的五大分区。 总览 iOS中,内存主要分为五大区域:栈区,堆区,全局区/静态区,常量区和代码区。总览图如下。 如上图所示,代码区是在低地址段存放&#x…

4. CSS用户界面样式

4.1什么是界面样式 所谓的界面样式,就是更改一些用户操作样式,以便提高更好的用户体验。 ●更改用户的鼠标样式 ●表单轮廓 ●防止表单域拖拽 4.2鼠标样式cursor li {cursor: pointer; }设置或检索在对象上移动的鼠标指针采用何种系统预定义的光标形状。 4.3轮廓线outline…

FTP挂载网络磁盘

项目中使用存储阵列或NAS等网络存储作为文件存储地址,服务器与存储之间通过网络进行传输,当我把ftp指向的存储地址修改为网络磁盘时,会出现550等读取不到目录问题;以下为解决方案: 1.在服务器中新增windows用户&#x…

2、JDk、JRE、JVM三者区别和联系

JDK JRE JVM 含义 JDK: Java Develpment Kit java 开发工具 JRE: Java Runtime Environment java 运行时环境 JVM: java Virtual Machine java 虚拟机 一张图来解释: 联系: JVM不能单独搞定class的执行,解释class的时候JVM需要调用解…

什么是CI/CD?让你的项目变得更加敏捷!

在今天这个快速变化的时代,开发者们需要与时俱进,不断提升自己的工作效率。在这篇文章里,将一起探讨如何使用CI/CD和Github Action让你的项目更加高效,快速响应市场变化。 一、什么是CI? CI(持续集成&…