定制软件开发【node进阶】深入浅出---MVC设计模式&RESTful风格

✅ 作者简介:定制软件开发一名普通本科大三的学生,定制软件开发致力于提高前端开发能力
✨ 个人主页:
🔥 系列专栏 :
⭐️ 个人社区 :
🍀 学习格言: ☀️ 定制软件开发打不倒你的会使你更强!☀️
💯 刷题网站:定制软件开发这段时间有许多的小伙定制软件开发伴在问有没有什么好的刷题网站,定制软件开发博主在这里给大家推荐定制软件开发一款刷题网站:👉👈定制软件开发牛客网支持多种编程语言的学习,定制软件开发各大互联网大厂面试真题,定制软件开发从基础到拔高,定制软件开发快来体验一下吧!


🔥前言

定制软件开发在前面的文章我们已经定制软件开发会写接口了,但是接口不能瞎写啊,必须要具备规范性,同时为了使我们写的代码更容易维护,必须要学会业务分层(MVC),这样的话使相应的人做相应的事情,接下来正文开始!

📃目录

接口规范

架构

  • 为什么要用RESTful
    在以往我们去写接口的时候,我们总是自己去命名,虽然不影响正常的使用,但是当你进入到一个大一点的开发团队里面你得遵循团队的接口规范,大多数团队用的就是RESTful规范(当然,不是所有的团队都是,但是你通过学习RESTful就可以轻松入手其他的规范,道理是相差无几的),为了能够无缝衔接的进入到团队开发,RESTful架构是值得学习的。
  • 通俗理解RESTful
    RESTful就是对自己写的接口进行规范化,使用RESTful架构可以充分的发挥GETPOSTPUTDELETE 四种请求方式的意义,简单的来说url地址中只包含名词表示资源,使用http的动词(GET | POST | PUT | DELTE)表示要进行的动作进行操作资源
  • 举例
    • 错误的设计方式

      //添加用户router.post('/user/addUser',(req,res)=>{  //...})//更新用户信息router.put('/user/updateUser',(req,res)=>{  //...})//删除用户router.delete('/user/delUser',(req,res)=>{  //...})//获取用户信息router.get('/user/getUser',(req,res)=>{  //...})
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • 正确的设计方式

      //添加用户router.post('/user',(req,res)=>{  //...})//更新用户信息router.put('/user/:id',(req,res)=>{  //...})//删除用户router.delete('/user/:id',(req,res)=>{  //...})//获取用户信息router.get('/user',(req,res)=>{  //...})
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16

      注意:后端要跟前端进行语义化的规定,统一战线!例如:想要获取用户信息,前端发送GET请求即可…


使用方式

REST要求,必须通过统一的接口来对资源执行各种操作:

请求方式URL解释
GEThttp://localhost:8080/user获取全部用户信息
GEThttp://localhost:8080/user/1 (1是id参数值,同时也是请求路径的一部分)获取单个信息
POSThttp://localhost:8080/user创建用户
PUThttp://localhost:8080/user/1更新 id为1的员工信息
DELETEhttp://localhost:8080/user/2删除 id为2的用户信息
HEAD获得一个资源的元数据,比如一个资源的hash值或者最后修改日期
OPTIONS获得客户端针对一个资源能够实施的操作,获取该资源的api

过滤信息

一般情况下我们只是把?简单的当做是参数的传递,很容易造成url过于复杂、难以理解。可以把?用于对资源的过滤.
例如:

请求方式URL解释
GEThttp://localhost:8080/user?page=2&limit=5指定获取到第2页数据,限制每一页5条数据
GEThttp://localhost:8080/user?sortby=name&order=asc指定获取数据按照名字排序,以及按照acs排序
GEThttp://localhost:8080/user?state=close可以自定义设置筛选条件

注意:我们在进行筛选的时候一定要与后端做好约定。


业务分层

设计模式

MVC应该是编程界众所周知的,M即Model,V即View,C即Controller。分别对应我们的业务模型,用户界面控制器。用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。

上面一直用官方的话来说,大家肯定觉得比较抽象,下面我以画图的形式展现了出来(画的不好,大家应该可以看懂),MVC每层之间的逻辑关系:

controller:C层负责业务逻辑(view与model之间的桥梁)
view:V层负责展现页面
model:M层负责处理数据(连接数据库进行增删改查)


中使用MVC思想

在这里先分享一下node中的MVC是怎么样实现的,如下图所示:


node中MVC实现代码(RESTful+MVC)

通过上图我们了解到了MVC思想在node中怎么执行的,接下来,我们通过代码进行分析:

  1. 代码架构

  2. db.config.js(连接数据库

    //链接数据库const mongoose = require("mongoose")mongoose.connect("mongodb://127.0.0.1:27017/lzq_project")//插入集合和数据,数据库lzq_project会自动创建
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
  3. UserService.js(创建模型,配置数据库信息)

    const mongoose = require('mongoose')const UseeType = {    username : String,    password : String,    age : Number}const UserModel = mongoose.model('user',new mongoose.Schema(UseeType))//模型user 将会对应 users 这个集合,module.exports = UserModel
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
  4. user.js(用户路由模块)

    var express = require('express');const UserController = require('../controllers/UserController');var router = express.Router();/* GET users listing. */router.get('/', function(req, res, next) {  res.send('respond with a resource');});//相应前端post请求-增加用户router.post('/user',UserController.addUser)//动态路由,获取idrouter.put('/user/:id',UserController.updateUser)//删除请求  restfulrouter.delete('/user/:id',UserController.delUser)router.get('/user',UserController.getUser)module.exports = router;
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
  5. UserModel.js(M层,业务逻辑实现数据库增删改查)

    const UserModel = require("../model/UserModel")const UserService = {    addUser : (username,password,age) => {        return UserModel.create({username,password,age})    },    updateUser : (_id,username,password,age)=>{        return UserModel.updateOne({_id},{            username,password,age          })    },    delUser : (_id) => {        return UserModel.deleteOne({_id})    },    getUser : (page,limit) => {        return UserModel.find({},["username","age"]).skip((page-1)*limit).limit(limit).sort({age:-1})//年龄倒序排列---  -1   正序   1    }}module.exports = UserService
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
  6. UserController.js(C层,把M层的数据给V层)

    const UserService = require("../services/UserService");const UserController = {    addUser: async (req,res)=>{        console.log(req.body);        //插入数据库        // 1.创建模型,一一对应数据库的集合(users)        const {username,password,age} = req.body        await UserService.addUser(username,password,age)        res.send({            ok:1          })    },    //更新用户信息的回调函数    updateUser: async (req,res)=>{        console.log(req.body,req.params.id);        const {username,password,age} = req.body        await UserService.updateUser(req.params.id,username,password,age)        res.send({ok:'ok'})    },    delUser : async (req,res)=>{        await UserService.delUser(req.params.id)        res.send({ok:'1'})    },    getUser : async (req,res)=>{         console.log(req.query);        const {page,limit} = req.query        const data = await UserService.getUser(page,limit)        res.send(data)      }}module.exports = UserController
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
  7. index.ejs(V层,前端显示的页面)

    <body>  <h1>mongoDB增删改查的演示</h1>  <div>    <div>用户名:<input id="username" /></div>    <div>密码:<input type="password" id="password" /></div>    <div>年龄:<input type="age" id="age" /></div>    <div><button id="register">注册</button></div>  </div>  <hr>  <div>    <button id="update">更新</button>    <button id="del">删除</button>  </div>  <hr>  <table border="1">    <thead>      <tr>        <td>id</td>        <td>用户名</td>        <td>年龄</td>        <td>操作</td>      </tr>    </thead>    <tbody>    </tbody>  </table>  <script>    let name = document.querySelector('#username')    let psd = document.querySelector('#password')    let age = document.querySelector('#age')    register.onclick = () => {      console.log(name.value, psd.value, age.value);      fetch("/api/user", {        method: 'post',        body: JSON.stringify({          username: name.value,          password: psd.value,          age: age.value        }),        headers: {          "Content-Type": "application/json"        }      }).then(res => res.json())        .then(res => {          console.log(res);        })    }    update.onclick = () => {      fetch("/api/user/634f5d8ed2922eaf4a9972b1", {        method: 'put',        body: JSON.stringify({          username: "修改的名字",          password: "修改的密码",          age: 20        }),        headers: {          "Content-Type": "application/json"        }      }).then(res => res.json())        .then(res => {          console.log(res);        })    }    del.onclick = () => {      fetch("/api/user/634f5d8ed2922eaf4a9972b1",{        method:'DELETE'      }).then(res => res.json())        .then(res => {          console.log(res);        })    }    fetch("/api/user?page=1&limit=5").then(res => {      return res.json()    }).then(res => {      console.log(res);      let tbody = document.querySelector('tbody')      tbody.innerHTML = res.map(item => {        return `<tr>              <td>${item._id}</td>              <td>${item.username}</td>              <td>${item.age}</td>              <td><button data-id="${item._id}" id="btn">更新</button> <button data-id="${item._id}" id="del">删除</button></td>             </tr>`      }).join('')      tbody.onclick = (event) => {        console.log(event.target);        if (event.target.id === "btn") {          fetch(`/api/user/${event.target.dataset.id}`, {            method: 'post',            body: JSON.stringify({              username: "以后绝不压竞猜&阿修",              age: 22            }),            headers: {              "Content-Type": "application/json"            }          }).then(res => res.json())            .then(res => {              fetch("/api/user?page=1&limit=5").then(res => res.json())                .then(res => {                  tbody.innerHTML = res.map(item => {                    return `<tr>              <td>${item._id}</td>              <td>${item.username}</td>              <td>${item.age}</td>              <td><button data-id="${item._id}" id="btn">更新</button> <button data-id="${item._id}" id="del">删除</button></td>             </tr>`                  }).join('')                })            })        }        if (event.target.id === 'del') {          console.log(event.target.id);          fetch(`/api/user/${event.target.dataset.id}`).then(res => res.json()).then(res => {            fetch("/api/user?page=1&limit=5").then(res => res.json())              .then(res => {                tbody.innerHTML = res.map(item => {                  return `<tr>              <td>${item._id}</td>              <td>${item.username}</td>              <td>${item.age}</td>              <td><button data-id="${item._id}" id="btn">更新</button> <button data-id="${item._id}" id="del">删除</button></td>             </tr>`                }).join('')              })          })        }      }    })  </script></body>
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111
    • 112
    • 113
    • 114
    • 115
    • 116
    • 117
    • 118
    • 119
    • 120
    • 121
    • 122
    • 123
    • 124
    • 125
    • 126
    • 127
    • 128
    • 129
    • 130
    • 131
    • 132
    • 133
    • 134
    • 135
    • 136
  8. 最终效果

MVC的优缺点

从上面的代码中可以观察得出来一个事情,我们的代码结构很清晰,分离一层一层去写,方便维护,但是同时发现项目明显的便复杂了,所以总结了MVC的优缺点:
MVC的优点

  1. 耦合性低,方便维护,可以利于分工协作
  2. 代码的复用性比较强

MVC的缺点:
项目变得的确优点复杂,对书写代码的小伙伴们要求得比较多


小结

大家跟我的node专栏学习走到这里就可以发现一个有趣的事情:node+express+RESTful+MVC嘎嘎好用,其实到这里你的node可以进行适当的开发了,后面的文章加一个身份验证以及写一个全栈项目,node就要完结了,所以下一篇就是我们的身份验证,同时还要更新【node番外】mongoDBmysql两个数据库哦,以及node连接数据库。
少年,继续加油吧!😀😀


👑书写不易,希望大家能够给予三连支持,期待我更好的文章哟👑

网站建设定制开发 软件系统开发定制 定制软件开发 软件开发定制 定制app开发 app开发定制 app开发定制公司 电商商城定制开发 定制小程序开发 定制开发小程序 客户管理系统开发定制 定制网站 定制开发 crm开发定制 开发公司 小程序开发定制 定制软件 收款定制开发 企业网站定制开发 定制化开发 android系统定制开发 定制小程序开发费用 定制设计 专注app软件定制开发 软件开发定制定制 知名网站建设定制 软件定制开发供应商 应用系统定制开发 软件系统定制开发 企业管理系统定制开发 系统定制开发