我们的应用程序将有五个不同的层,它们将以这种方式排序:

文章插图
应用层
- 应用层将具有我们服务器的基本设置以及与我们的路由(下一层)的连接 。
- 路由层将定义我们所有的路由以及与控制器(下一层)的连接 。
- 控制器层将具有我们想要在每个端点中执行的实际逻辑以及与模型层的连接(下一层,你明白了......)
- 模型层将保存与我们的模拟数据库交互的逻辑 。
- 最后,持久层是我们的数据库所在的位置 。
您可以看到这种方法更加结构化,并且具有明确的关注点划分 。这听起来像是很多样板 。但是在设置好之后,这个架构将让我们清楚地知道每个东西在哪里,以及哪些文件夹和文件负责我们的应用程序执行的每个操作 。
要记住的重要一点是,在这类架构中,必须遵循层之间定义的通信流才能使其有意义 。
这意味着请求首先必须通过第一层,然后是第二层,然后是第三层,依此类推 。任何请求都不应该跳过层,因为这会破坏架构的逻辑以及它给我们带来的组织和模块化的好处 。

文章插图
描绘我们的架构的另一种方式
现在让我们看一些代码 。使用层架构,我们的文件夹结构可能如下所示:

文章插图
- 我们有一个名为的新文件夹db,它将保存我们的数据库文件 。
- 另一个名为的文件夹rabbits将保存与该实体相关的路由、控制器和模型 。
- app.js设置我们的服务器并连接到路由 。
// App.js const express = require('express'); const rabbitRoutes = require('./rabbits/routes/rabbits.routes') const app = express() const port = 7070 /* Routes */ app.use('/rabbits', rabbitRoutes) app.listen(port, () => console.log(`??[server]: Server is running at http://localhost:${port}`))- rabbits.routes.js保存与该实体相关的每个端点并将它们链接到相应的控制器(当请求到达该端点时我们想要执行的函数) 。
// rabbits.routes.js const express = require('express') const bodyParser = require('body-parser') const jsonParser = bodyParser.json() const { listRabbits, getRabbit, editRabbit, addRabbit, deleteRabbit } = require('../controllers/rabbits.controllers') const router = express.Router() router.get('/', listRabbits) router.get('/:id', getRabbit) router.put('/:id', jsonParser, editRabbit) router.post('/', jsonParser, addRabbit) router.delete('/:id', deleteRabbit) module.exports = router- rabbits.controllers.js持有每个端点对应的逻辑 。在这里,我们编写函数应该将什么作为输入,它应该执行什么过程以及它应该返回什么 。此外,每个控制器都链接到相应的模型函数(将执行数据库相关操作) 。
// rabbits.controllers.js const { getAllItems, getItem, editItem, addItem, deleteItem } = require('../models/rabbits.models') const listRabbits = (req, res) => { try { const resp = getAllItems() res.status(200).send(resp) } catch (err) { res.status(500).send(err) } } const getRabbit = (req, res) => { try { const resp = getItem(parseInt(req.params.id)) res.status(200).send(resp) } catch (err) { res.status(500).send(err) } } const editRabbit = (req, res) => { try { const resp = editItem(req.params.id, req.body.item) res.status(200).send(resp) } catch (err) { res.status(500).send(err) } } const addRabbit = (req, res) => { try { console.log( req.body.item ) const resp = addItem(req.body.item) res.status(200).send(resp) } catch (err) { res.status(500).send(err) } } const deleteRabbit = (req, res) => { try { const resp = deleteItem(req.params.idx) res.status(200).send(resp) } catch (err) { res.status(500).send(err) } } module.exports = { listRabbits, getRabbit, editRabbit, addRabbit, deleteRabbit }- rabbits.models.js是我们定义将在我们的数据库上执行 CRUD 操作的函数的地方 。每个函数代表一种不同类型的操作(读取一个、读取所有、编辑、删除等) 。该文件是连接到我们的数据库的文件 。
// rabbits.models.js const db = require('../../db/db') const getAllItems = () => { try { return db } catch (err) { console.error("getAllItems error", err) } } const getItem = id => { try { return db.filter(item => item.id === id)[0] } catch (err) { console.error("getItem error", err) } } const editItem = (id, item) => { try { const index = db.findIndex(item => item.id === id) db[index] = item return db[index] } catch (err) { console.error("editItem error", err) } } const addItem = item => { try { db.push(item) return db } catch (err) { console.error("addItem error", err) } } const deleteItem = id => { try { const index = db.findIndex(item => item.id === id) db.splice(index, 1) return db return db } catch (err) { console.error("deleteItem error", err) } } module.exports = { getAllItems, getItem, editItem, addItem, deleteItem }
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 事件驱动架构的优点和面临的挑战
- 在云端使用 Redis? 以下是你应该知道的十件事
- 20 个 Python 面试题来挑战你的知识
- 嵌入式开发如何入门?
- Spring Cloud Alibaba-全局配置自定义和支持的配置项
- MinIO OSS服务器的搭建和应用
- 陈萌|陈萌开车接朱小伟回家,介怀陈亚男的存在?称不愿做2婚妻子
- 小叶紫檀|盘点那些招财的翡翠!你有几件?
- 黄山最值得去的五个景点 黄山市旅游景点
- 职场中有效的抱怨是你晋升的阶梯
