REST-API-09-Body-Validation

Body Validation

使用 JOI 对以 body 形式提交的数据,进行校验。

在 routerHelper 中配置各种校验。

helpers/routerHelpers.js

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
//helpers/routerHelpers.js
const Joi = require('joi');
module.exports = {
validateParam:(schema,name) => {
return (req,res,next) => {
const result = Joi.validate({[name]:req['params'][name]},schema);
if(result.error){
console.error(result.error);
return res.status(400).json(result.error);
}else{
if(!req.value){
req.value = {};
}
if(!req.value['params']){
req.value['params'] = {};
}
req.value['params']= result.value;
next();
}
}
},
validateBody:(schema) =>{
return(req,res,next) => {
const result = Joi.validate(req.body,schema);
if(result.error){
console.error(result.error);
return res.status(400).json(result.error);
}else {
if(!req.value){
req.value = {}
}
if(!req.value['body']){
req.value['body'] = {};
}
req.value['body'] = result.value;
next();
}
}
},
schemas: {
userSchema:{
firstName: Joi.string().required(),
lastName:Joi.string().required(),
email:Joi.string().email().required()
},
userOptionalSchema:{
firstName: Joi.string(),
lastName:Joi.string(),
email:Joi.string().email()
},
idSchema: Joi.object().keys({
userId:Joi.string().regex(/^[0-9a-fA-F]{24}$/).required()
}),
carSchema: Joi.object().keys({
make:Joi.string().required(),
model:Joi.string().required(),
year:Joi.number().required()
})
}
}
const idSchema = Joi.object().keys({
userId:Joi.string().regex(/^[0-9a-fA-F]{24}$/).required()
});

routers/users.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//routers/users.js
const express = require('express');
const router = require('express-promise-router')();
const userController = require('../controllers/users');
const { validateParam, validateBody,schemas } = require('../helpers/routerHelpers');
router.route('/')
.get(userController.index)
.post(validateBody(schemas.userSchema),userController.newUser);
router.route('/:userId')
.get(validateParam(schemas.idSchema, 'userId'),userController.getUser)
.put([validateParam(schemas.idSchema, 'userId'),validateBody(schemas.userSchema)], userController.replaceUser)
.patch([validateParam(schemas.idSchema, 'userId'),validateBody(schemas.userOptionalSchema)],userController.updateUser);
router.route('/:userId/cars')
.get(validateParam(schemas.idSchema, 'userId'),userController.getUserCars)
.post([validateParam(schemas.idSchema, 'userId'),validateBody(schemas.carSchema)],userController.newUserCar);
module.exports = router;

controllers/users.js

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
\\controllers/users.js
const User = require('../models/user');
const Car = require('../models/car');
module.exports = {
index: async (req, res, next) => {
const users = await User.find();
//throw new Error('Dummy error !');
res.status(200).json(users);
},
newUser: async (req, res, next) => {
const newUser = new User(req.value.body);
const user = await newUser.save();
res.status(200).json(user);
},
getUser: async (req, res, next) => {
const { userId } = req.value.params;
const users = await User.findById(userId);
res.status(200).json(users);
},
replaceUser: async (req, res, next) => {
const { userId } = req.params;
const newUser = req.body;
const result = await User.findByIdAndUpdate(userId, newUser);
res.status(200).json({ success: true });
},
updateUser: async (req, res, next) => {
const { userId } = req.params;
const newUser = req.body;
const result = await User.findByIdAndUpdate(userId, newUser);
res.status(200).json({ success: true });
},
getUserCars: async (req, res, next) => {
//const result = Joi.validate(req.params,idSchema);
const { userId } = req.params;
const user = await User.findById(userId).populate('cars');
res.status(200).json(user.cars);
},
newUserCar: async (req, res, next) => {
const { userId } = req.params;
// Create a new car
const newCar = new Car(req.body);
// Get user
const user = await User.findById(userId);
// Assign user as a car's seller
newCar.seller = user;
// Save the car
await newCar.save();
// Add car to the user's selling array 'cars'
user.cars.push(newCar);
// Save the user
await user.save();
res.status(201).json(newCar);
}
}

代码

https://github.com/monk8/expressjs-rest-api-server/tree/lesson09

参考
https://www.bilibili.com/video/av11683622/#page=9