1. 概述

时间跨度有点大,之前就跟大家唠嗑过一些知识点,也开启了一个Node书写一个后台api项目的开始,出于各种原因,迟迟没有更新博文。现在我把这个坑填上,如果你还有阅读过我之前的文章,我建议你先阅读一下

博文地址https://www.cnblogs.com/BM-laoli/p/12708342.html

项目Git地址 https://github.com/BM-laoli/Node-api-Design 所有代码已经分章节的放在了github供需要的朋友参考

在接下来的项目中,我将尽量的以工作时的状态,或者说完全按照公司工作的标准流程,来进行开发,git上分章节,创建分支都是必须学的基本技能,

2. 初始化(github相关)

我们这里假设一种情况,就是你进到一家公司,公司新的项目还没有开始,目前是做的旧的项目,(假设旧的项目在github上),突然你的上司跟你说,你今天做一个对某项目(这里假设旧是我们的design)做一个CRUD接口,然后你上司丢给你一个gihub地址,那你怎么办?蒙圈了???,你这个时候去问人....就有点傻逼了,因为你这都不会,你还来公司干啥?干坐着?

好了毒鸡汤灌输完毕,接下里我们就来开始我们的项目

2.1. 设计架构的更新

  • 首先我们看看我们的之前的设计图,再看看我们现在的总体架构图

2.2 看看我们接下需要做哪些事情,

我们希望写几个接口对两个数据表进行操作这两个表是 article 还有user

  • 关于架构的设计模式还有一些规则,

大佬不要喷我,这里就说一下,我的个人观点,项目的架构,基本上都是MVC,既然是MVC那么这里就得非常的明确的分出来,(如果你学习过后台的语言比如php或者java)那么这个应该能非常好理解,在node中的架构是这样的,

我们站在http发送的报文角度,看看我们的的报文从客户端发到我们node服务器,经历了哪些事情

--> 进入路由 -----> 路由接受到之后做业务处理,这里就是(中间件)业务处理的逻辑就是在中间件做的-------> 假设你的http报文要请求数据库的一些字段,那么久需要用到model层<------数据库的dao层(在node中你可能使用的别人大神给你写好的dao层比如mongoose,或则Knex.js等,总而言之这些东西都是为model服务的) ------>中间件抛出数据next到我们的路由上------->路由通过res.send把数据丢出去,提示:在node中我们最常用的就是把传出去的数据整成json格式,如果你还不会,别着急我们一点点来学

2.3 克隆项目下来

git clone https://github.com/BM-laoli/Node-api-Design.git

3. 进入业务之前的说明

3.1 想清楚再敲代码,别一上来就吧唧敲一顿

我们看看啊,我们的大体的流程,理解整个的流程,丢代码的书写非常的重要,这样你就能清晰的知道自己到底在干嘛了.

还有一点需要说明的是:这里我们遵守这样的一个命名规范:数据模型是大写单数,路由参数是小写复数比如

Article ====> articles

3.2 接口测试工具

我们使用一个vs上的一个插件这个插件是下面的样子,在项目中,我讲一点点的教大家使用它

4. 进入业务

4.1 设计数据库并且完成连接

这里我们主要干的一个事情就是设计两个集合(表),并且拿到他们的操作对象

  1. 新建一个分支init-database,
git checkout -b init-basese

这里我们新建一个分支,并且配置一个忽略项文件

.gitignore

.DS_Store
node_modules
npm-debug.log
package-lock.json

以上的代码表示我们在git上提交东西的时候可以忽略掉node_module,等文件夹/文件

  1. 在molde下设计一个article表(集合),它的规则(schema)如下

/model/Article

const mongoose = require('mongoose')
const schema = new mongoose.Schema({ title:{ type:String },
body:{type:String} }) module.exports = mongoose.model( 'Article',schema )
  1. 提交给git分支,并且合并一下代码待maseter上

git push origin init-basese

4.2 实现丢article表的增删改查(CRUD)

首先我们依然是git出来一个分支,我们在CRUD分支下进行操作

git checkout -b CRUD

注意,这里我在原来的基础上做了一些修改,因为使用restClinet的时候有些字段不能读取出来,所有我修改了下面的代码

  • 在main下 我把原来的index接口改掉了,改造成了下面的这样的格式,然后在home.index.js中也稍微做了一下修改

    /main.js
require('./API/home/index')(admin)
实际上这样的写法等价于。
main.use(require('./API/home/index'))

/home/index.js

module.exports = admin => {
const express = require('express')
const router = express.Router({})
const Article = require('../../../../model/Article') //测试路由
router.get('/test',(req,res)=>{
res.send('ok')
}) //这句use一定要加
admin.use('/CRUD',router)
}
  • 在路由验证器的东西上,我改掉了header.token。因为我在发生restClint的时候,不走token,而是加在了Authorization字段中

    /Mideleware/loginPash.js
let token = req.headers.authorization;
  • 测试结果,注意这这里我使用了restClint插件,通过下面的图,你应该可以非常清晰的看到如何使用这个插件。非常方便的做接口测试

接下里就是正式的增删改查业务流程了

特别说明:这里我们编写的接口要求符合REST风格,至于说明是REST风格请去百度,它看起来就是下面的这个样子

更具REST风格来说。PUT表示更新,POST表示增加,DELET表示删除,GET分为带参数还有不带参数的情况,不带参数表示全查,待参数表示查指定内容
@uri = http://localhost:3000/main/CRUD
@toke = eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjoiNWU5MTIwMTViOWI0NmYzZmE4Y2MzMjUzIiwiZXhwIjoxNTg5ODU0NTI5LCJpYXQiOjE1ODk4NTI3Mjl9.U0N1bZLUBiy2fmz1NqAF-tTelE7uO8Xld4HHFeBsbq7iY5rSNMByYUyxhC1k8ug9n_8XzChL81ruiFuwxIcOg7DXk_hdrnvpUgwwtjIPjn4kfWWVEsZGm456fo3L5cHfppOTWH5NQAtKEd7xwrhqPrEPsBUwAc7pKEAFDaGuFOc ###
GET http://localhost:3000/main/test ### 进行token校验拿到我们的token,只有拿到token之后才允许进入下面的请求环节 POST http://localhost:3000/main/login
Content-Type: application/json {
"email":"18376621755@163.com",
"password":"123456"
} ### 我们需要携带token才能发起其它的请求
GET {{uri}}/test
Authorization: {{toke}} ### 增
POST {{uri}}/Article/
Content-Type: application/json
Authorization:{{toke}} {
"title":"分类测试3",
"body":"<h1>你好我是标题2</h1>"
} ### 删
DELETE {{uri}}/Article/5ec330fe21d3d97d5054e5bf
Authorization: {{toke}} ### 改
PUT {{uri}}/Article/5ec32f60cd080550a4e2fba8
Content-Type: application/json
Authorization:{{toke}} {
"title":"修改测试--222",
"body":"<h1>你好我是标题2</h1>"
} ### 查
GET {{uri}}/Article
Authorization:{{toke}} ### 查 根据id查
### 特别小心由于你在后台使用了express的动态路由,所以你不必加id=xxx
GET {{uri}}/Article/5ec32f60cd080550a4e2fba8
Content-Type: application/json
Authorization:{{toke}}

/home/index.js

module.exports = admin => {
const express = require('express')
const router = express.Router({
mergeParams: true //合并所有的url,如果你合并那么那个动态的resoulce你是拿不到的
})
const Article = require('../../../../model/Article') //测试路由
router.get('/test',(req,res)=>{
res.send('ok')
}) //增
router.post('/Article', async (req, res) => {
const model = await Article.create(req.body)
res.send(model)
}) //查
router.get('/Article', async(req, res,next) => {
const items = await Article.find().limit(10)
res.send(items)
next()
}) //根据id查
router.get('/Article/:id', async(req, res) => { console.log('asdasdasd');
console.log(req.params.id);
const items = await Article.findById(req.params.id)
res.send(items)
}) //更新(改)
router.put('/Article/:id', async(req, res) => {
const items = await Article.findByIdAndUpdate(req.params.id, req.body)
res.send(items)
}) //根据id参数(删)
router.delete('/Article/:id', async(req, res) => {
await Article.findByIdAndDelete(req.params.id, req.body)
res.send({
sucees: true
})
}) admin.use('/CRUD',router)
}

4.3 使用RESTClinet进行接口测试

  • 测试结果如下:完美通过

4.4 收尾上传分支到git

git push origin CRUD

4.4 抽离成一个通用的CRUD

现在老板又给我吗要求了,我们需要对一个名字叫做product集合(表),进行增删改查,那么问题来了?我们难道又要写一个与上代码类似的接口吗?

答案是非必要的,我们可以把上面的接口改成通用的CRUD,这样我们就能很方便的使用它了,有新的需求来的时候,只需要修改数据模型就好了

  • 首先,我们在路由的地方做一层封装

这里呢,我们就使用到了,之前的命名约定规范,(命名规范非常的重要!!!),我们使用一个第三方插件,实现大小写以及单复数的转换,然后根据转换之后的结果去找对应的 数据模型就好了

module.exports = admin => {
const express = require('express')
const inflection = require('inflection')
const router = express.Router({
mergeParams: true //合并所有的url,如果你合并那么那个动态的resoulce你是拿不到的
})
++++
//起一个到哪个台的资源就好了,注意我们的中间件
admin.use('/CRUD/rest/:resource', async(req, res, next) => { //转化成单数大写的字符串形式
let moldeName = inflection.classify(req.params.resource)
console.log(moldeName); //categorys ===> Category
//注意这里的关联查询populate方法,里面放的就是一个要被关联的字段
req.Model = require(`../../../../model/${moldeName}`)
req.modelNmae = moldeName
next()
}, router) }

设置好一层用来的过滤中间件之后,那么我们的CRUD就变成了一个通用的接口了,后续的操作API只需要变化接口的名字,变化数据库模型就好了,非常的方便,


//增
router.post('/', async (req, res) => {
const model = await req.Model.create(req.body)
res.send(model)
}) //查
router.get('/', async(req, res,next) => {
const items = await req.Model.find().limit(10)
res.send(items)
next()
}) //根据id查
router.get('/:id', async(req, res) => { console.log('asdasdasd');
console.log(req.params.id);
const items = await req.Model.findById(req.params.id)
res.send(items)
}) //更新(改)
router.put('/:id', async(req, res) => {
const items = await req.Model.findByIdAndUpdate(req.params.id, req.body)
res.send(items)
}) //根据id参数(删)
router.delete('/:id', async(req, res) => {
await req.Model.findByIdAndDelete(req.params.id, req.body)
res.send({
sucees: true
})
})

接下来我们新建一个product模型进行测试

/model/Prodcut

const mongoose = require('mongoose')
const schema = new mongoose.Schema({ product_name:{ type:String },
category:{type:String} }) module.exports = mongoose.model( 'Product',schema )

测试结果如下

Node教程——API接口开发(Node版的CRUD通用接口的搭建)(MangoDB+Express_Version2)的更多相关文章

  1. 支付宝WAP支付接口开发(Node/Coffee语言)

    此博客不更新很久了, 更新的文档在这, 有兴趣到这里围观: http://neutra.github.io/2013/%E6%94%AF%E4%BB%98%E5%AE%9DWAP%E6%94%AF%E ...

  2. Node.js 从零开发 web server博客项目[接口]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  3. api 接口开发理论 在php中调用接口以及编写接口

    如: http://localhost/openUser.php?act=get_user_list&type=json 在这里openUser.php相当于一个接口,其中get_user_l ...

  4. Node教程——API接口开发(MangoDB+Express)

    一.大纲 大纲: 关于架构, 首先我们的有一个app.js这个就是根路由起点,用来最初的打入口 它的功能有: 1.1 引入模块创建基础的网站服务器, 1.2 导入bodyPasser,过滤还有处理我们 ...

  5. 【Node.js】2.开发Node.js选择哪个IDE 开发工具呢

    安装完Node.js之后,就要为它选择一个有利的IDE用于开发. 相比较了多个IDE之后,定位在webstrom和sublime上. 有一个简单的比较: webstorm功能很丰富,前端开发工具的集大 ...

  6. 最详细的 paypal 支付接口开发--Java版

    做全球性的支付,选用paypal!为什么选择paypal? 因为paypal是目前全球最大的在线支付工具,就像国内的支付宝一样,是一个基于买卖双方的第三方平台.买家只需知道你的paypal账号,即可在 ...

  7. HTTP接口开发专题四(接收http接口发送过来的请求)

    前面讲了调用http接口的操作,这篇讲下接收http接口的操作.(以Spring MVC为例) 1)如果发送过来的内容类型是application/x-www-form-urlencoded ,则按照 ...

  8. Node.js 从零开发 web server博客项目[express重构博客项目]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

  9. Node.js 从零开发 web server博客项目[数据存储]

    web server博客项目 Node.js 从零开发 web server博客项目[项目介绍] Node.js 从零开发 web server博客项目[接口] Node.js 从零开发 web se ...

随机推荐

  1. 关于MySQL数据库存储过程的感想

    以下只是学习路上的浅薄感想,如理解有所偏差,还请有识之士指正! 一.存储过程意义理解 关于存储过程,我的理解是对数据库语言进行编程调用,就像Java代码类编程写一个具有某种特定功能的方法去进行调用一样 ...

  2. IDEA 之 ERROR:无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core]

    问题描述:在使用IDEA对JSTL进行测试时出现error:无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core] ...

  3. 【Linux常见命令】seq命令

    seq - print a sequence of numbers seq命令用于以指定增量从首数开始打印数字到尾数,即产生从某个数到另外一个数之间的所有整数,并且可以对整数的格式.宽度.分割符号进行 ...

  4. HTML中使用CSS样式(下)

    上节内容回顾加补充: 补充:默认img标签,有一个1px的边框 如果点击图片跳转到连接,a标签下套img标签,在IE有的版本中,会有蓝色边框. <a href="http://blog ...

  5. OpenWrt-19.07.2 For HC5861(极路由3) /HiWiFi/Gee最新固件,极路由3刷openwrt

    OpenWrt For HiWiFi(HC5861) 自编译精减固件,极路由3自用固件 HC5861-uboot.bin v19.07.2 下载 支持 NTFS 读写 支持 Wi-Fi 5G 驱动 默 ...

  6. Android Studio快捷键动态演示

    Android Studio出来很久了,大部分已经转过来了,相对于Eclipse又是毋庸置疑,更好的使用快捷键必定达到事半功倍的效果. 友情提示:某些电脑按F1-F12键需要先按住FN,比如我的Mac ...

  7. Spring PropertyPlaceholderConfigurer类载入外部配置

    2019独角兽企业重金招聘Python工程师标准>>> 通常在Spring项目中如果用到配置文件时,常常会使用org.springframework.beans.factory.co ...

  8. Azkaban3.81.x部署+坑

    一.前提安装 1.1 Java1.8环境搭建 1) 下载jdk1.8并解压: # tar -zxvf jdk-8u201-linux-i586.tar.gz -C /usr/local 2) 添加Ja ...

  9. 图论--网络流--最大流--POJ 1698 Alice's Chance

    Description Alice, a charming girl, have been dreaming of being a movie star for long. Her chances w ...

  10. Nacos作为配置中心时,多个服务共用一个dataId的配置

    写在前面 本文是对我之前一篇文章<Spring Cloud+nacos+Feign,实现注册中心及配置中心>的补充.此文章中简单写了如何将Nacos作为配置中心.在使用配置中心时,我们会遇 ...