I have some trouble validating my nested object request body with "express-validator" package. Let's say we have a method to collect user input with a body like this :
{
"general": {
"sessionId": "a2957207-e033-49e7-b9da-1c5f946a1074",
"os": "android",
"vendor": "htc"
},
"data": [
{
"target": "logPageVisits",
"pageName": "users/packages",
"engagementTime": 350
}
]
}
express-validator only offers validation like this :
req.checkBody('engagementTime')
.notEmpty()
.withMessage('Engagement-Time is required')
It seems there's no clean way to validated nested objects like this :
req.checkBody('data.engagementTime')
.notEmpty()
.withMessage('Engagement-Time is required')
I've found an closed issue on Github! but it doesn't fulfill my concerns!
Any better suggestions?
You can always create your custom middleware for express.
For example, in your case, very simplified it would look like this:
const checkNestedBodyMiddleware = (req, res, next) => {
const { data } = req.body;
// As I see, here is array in data, so we use simple find
const engTimeInArr = data.find(d => d.engagementTime);
if(!engTimeInArr){
return res.status(400).send('Engagement-Time is required');
}
next();
}
And then use it in your route:
app.post('/some-route', checkNestedBodyMiddleware, (req, res) => {
// your route logic here.
})
So, in this case you hide validation logic in middleware and can assign any number of middlewares to route.
Use .*.
for iterating this
req.checkBody('data.*.engagementTime')
.notEmpty()
.withMessage('Engagement-Time is required')
I am a bit late, but here is what you can do as of v6.12.0. To validate a schema, you can use checkSchema
method:
const { checkSchema } = require('express-validator');
checkSchema({
'general': {
in: 'body', // the location of the field
exists: {
errorMessage: 'Field `general` cannot be empty',
bail: true
},
isObject: {
errorMessage: 'Field `general` must be an object',
bail: true
}
},
// to check a nested object field use `object.nestedField` notation
'general.sessionId': {
trim: true,
isString: {
errorMessage: 'Field `sessionId` must be a string',
bail: true
}
},
'data': {
in: 'body',
exists: {
errorMessage: 'Field `data` cannot be empty',
bail: true
},
isArray: {
errorMessage: 'Field `data` must be an array',
bail: true
}
},
// use `*` to loop through an array
'data.*.engagementTime': {
notEmpty: {
errorMessage: 'Field `engagementTime` should not be empty',
bail: true
}
}
})
References:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With