【Node.js工程师养成计划】之express中间件与接口规范

一、Express中间件的概念与基本应用

const express = require('express')

// 加一个注释,用以说明,本项目代码可以任意定制更改
const app = express()

const PORT = process.env.PORT || 3000

// // 挂载路由
// app.use('/api', router)

// // 挂载统一处理服务端错误中间件
// app.use(errorHandler())

app.get('/', (req, res) => {
  console.log(`${req.method}, ${req.url}, ${Date.now()}`);
  res.send('/index')
})

app.get('/register', (req, res) => {
  console.log(`${req.method}, ${req.url}, ${Date.now()}`);
  res.send('/iregisterdex')
})

app.get('/login', (req, res) => {
  console.log(`${req.method}, ${req.url}, ${Date.now()}`);
  res.send('/login')
})

app.listen(PORT, () => {
  console.log(`Server is running at http://localhost:${PORT}`)
})

封装个方法:

const express = require('express')

// 加一个注释,用以说明,本项目代码可以任意定制更改
const app = express()

const PORT = process.env.PORT || 3000

function logs(req) {
  console.log(`${req.method}, ${req.url}, ${Date.now()}`);
  console.log(`${req.method}, ${req.url}, ${Date.now()}`);
  console.log(`${req.method}, ${req.url}, ${Date.now()}`);
}

app.get('/', (req, res) => {
  logs(req)
  res.send('/index')
})

app.get('/register', (req, res) => {
  logs(req)
  res.send('/iregisterdex')
})

app.get('/login', (req, res) => {
  logs(req)
  res.send('/login')
})

app.listen(PORT, () => {
  console.log(`Server is running at http://localhost:${PORT}`)
})

发现也并不完美

写个中间件

const express = require('express')

// 加一个注释,用以说明,本项目代码可以任意定制更改
const app = express()

const PORT = process.env.PORT || 3000

app.use((req, res, next) => {
  console.log(`${req.method}, ${req.url}, ${Date.now()}`);
  next()
})

// // 挂载路由
// app.use('/api', router)

// // 挂载统一处理服务端错误中间件
// app.use(errorHandler())

// 中间件写在要使用的逻辑前面
app.get('/', (req, res) => {
  res.send('/index')
})

app.get('/register', (req, res) => {
  res.send('/register')
})

app.get('/login', (req, res) => {
  res.send('/login')
})

app.listen(PORT, () => {
  console.log(`Server is running at http://localhost:${PORT}`)
})

二、不同中间件类别的使用方式

中间件分类:

  • 应用程序级别中间件
  • 路由级别中间件
  • 错误处理中间件
  • 内置中间件
  • 第三方中间件

1、应用程序级别中间件

const express = require('express')
const app = express()

const PORT = process.env.PORT || 3000

// 以下3个都是应用程序级别中间件
app.use((req, res, next) => {
  console.log(`${req.method}, ${req.url}, ${Date.now()}`);
  next()
})

app.get('/', (req, res) => {
  res.send('/index')
})

app.get('/user', (req, res, next) => {
  console.log(req.method)
  next()
}, function (req, res, next){
  console.log('666')
  next()
  res.send('/user')
})

app.listen(PORT, () => {
  console.log(`Server is running at http://localhost:${PORT}`)
})

2、路由级别中间件

router/index.js

const express = require('express')

const router = express.Router()

router.get('/', (req, res) => {
  console.log(req.methods)
  res.send('/index')
})

router.get('/user', (req, res) => {
  console.log(req.methods)
  res.send('/user')
})

module.exports = router

app.js

const express = require('express')
const app = express()
const router = require('./router/index')
const routerVideo = require('./router/video')

const PORT = process.env.PORT || 3000

// 挂载路由
// app.use(router)
app.use('/api', router) // 添加前缀
// app.use('/video', routerVideo) // 添加前缀

app.listen(PORT, () => {
  console.log(`Server is running at http://localhost:${PORT}`)
})

在这里插入图片描述

3、错误处理中间件

// 错误处理中间件
app.use((err, req, res, next) => {
  console.log(err)
  res.status(500).send('service Error')
})

4、 内置中间件

内置中间件

// app.use(express.urlencoded())
app.use(express.json())

5、第三方中间件

第三方中间件

三、Express路由与响应方法

// app.all不匹配路由方法(不区分get\post等)
app.all('/xx', (req,res) => {
  res.send('xxx')
})
app.get('/us?er', (req, res) => {
  res.send(`${req.method}---${req.url}`)
})
app.get('/user/:id', (req, res) => {
  console.log(req.params)
  res.send(`${req.method}---${req.url}`)
}) 
app.get('/user/:id/video/:vid', (req, res) => {
  console.log(req.params)
  res.send(`${req.method}---${req.url}`)
})

// 路由链式调用
app.get('/user', (req, res) => {

}).post('/video', (req, res) => {
  
})

router.get('/list', (req, res) => {
  console.log(req.methods)
  res.send('/video-list')
}).get('/user', (req, res) => {
  console.log(req.methods)
  res.send('/user')
})

express的响应方法

四、项目基础设计搭建优化

在这里插入图片描述
app.js

const app = express()

const PORT = process.env.PORT || 3000

// 中间件基本的使用
app.use(express.json())
// app.use(express.urlencoded())
app.use(cors()) // 跨域处理
app.use(morgan('dev')) // 日志记录(dev开发模式下)
app.use('/api/v1', router)


app.listen(PORT, () => {
  console.log(`Server is running at http://localhost:${PORT}`)
})

router/index.js

const express = require('express')
const router = express.Router()

router.use('./user', require('./user'))
router.use('./video', require('./video'))

module.exports = router

router/user.js

const express = require('express')
const router = express.Router()
const userController = require('../controller/userController')

router
.get('/list', userController.list)
.delete('/', userController.delete)

module.exports = router

userController.js

exports.list = async (req, res) => {
  console.log(req.methods)
  res.send('/user-list')
}

exports.delete = async (req, res) => {
  console.log(req, res)
}

router/video.js

const express = require('express')
const router = express.Router()
const videoController = require('../controller/videoController')

router.get('/list', videoController.list)

module.exports = router

videoController.js

exports.list = async (req, res) => {
  console.log(req.methods)
  res.send('/video-list')
}

exports.delete = async (req, res) => {
  console.log(req, res)
}

五、数据处理模块-mongoose

mongoose
让我们面对这样的困境, 编写MongoDB验证,转换和业务逻辑是非常麻烦的. 所以我们发明了Mongoose.

const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');

const Cat = mongoose.model('Cat', { name: String });

const kitty = new Cat({ name: 'Zildjian' });
kitty.save().then(() => console.log('meow'));

Mongoose为模型提供了一种直接的,基于scheme结构去定义你的数据模型。它内置数据验证, 查询构建,业务逻辑钩子等,开箱即用。

./model/index.js

const mongoose = require('mongoose')

async function main() {
  await mongoose.connect('mongodb://localhost:27017/test')
}
main().then(res => {
  console.log(res, 'mongo连接成功')
}).catch(err => {
  console.log(err)
})

// 定义模型
const user = new mongoose.Schema({
  name: {
    type: String,
    required: true
  },
  age: {
    type: Number,
    required: true
  }
})

// 操作模型
const userModel = mongoose.model('User', user) // 第一个参数是集合的名字+s
const u = new userModel({
  name: 'zm',
  age: 18
})

u.save().then(() => {
  console.log(666)
})

在这里插入图片描述
在这里插入图片描述

六、用户注册数据入库

在这里插入图片描述
./model/index.js

const mongoose = require('mongoose')

async function main() {
  await mongoose.connect('mongodb://localhost:27017/express-video')
}
main().then(res => {
  console.log(res, 'mongo连接成功')
}).catch(err => {
  console.log(err)
})

module.exports = {
  User: mongoose.model('User', require('./userModel'))
}

./model/userModel.js

const mongoose = require('mongoose')

const userScheme = new mongoose.Schema({
  username: {
    type: String,
    dafault: 'zzzzz'
    // required: true
  },
  password: {
    type: String,
    default: '123456'
    // required: true
  },
  // email: {
  //   type: String,
  //   required: true
  // },
  // phone: {
  //   type: String,
  //   required: true
  // },
  image: {
    type: String,
    default: null
  },
  createAt: {
    type: Date,
    default: Date.now()
  },
  updateAt: {
    type: Date,
    default: Date.now()
  }
})

module.exports = userScheme

./controller/userController.js

const { User } = require('../model/index')

exports.list = async (req, res) => {
  console.log(req.methods)
  res.send('/user-list')
}

exports.delete = async (req, res) => {
  console.log(req, res)
}

exports.register = async (req, res) => {
  console.log(1111, req.body)
  // res.send('/user-register')
  const userModel = new User(req.body)
  const dbBack = await userModel.save()
  res.status(201).json(dbBack)
}

在这里插入图片描述
在这里插入图片描述

七、用户注册的密码加密问题

正在更新。。。

  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

老电影故事

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值