This is my experience about validating request data using AdonisJS validator and the solution for it. I can't easily find an article about this issue so I decide to write this so that others which have the same issue could find the solution easier.
Context
This issue happened when I had a data block that need to submit to the backend to handle. Its format looks like this
{
"users": [
{
"name": "John Doe",
"avatar": <File>
},
...
]
}
And following the documents from AdonisJS, I use this snippet to validate the data
params = await request.validate({
schema: schema.create({
users: schema.array().members(
schema.object().members({
name: schema.string({ trim: true }),
avatar: schema.file({
size: '10mb',
extnames: ['jpg', 'heic']
}),
})
),
}),
})
Problem
The problem is that submitted data in the backend will be stored by AdonisJS in 2 parts, request.all()
and request.allFiles()
. So the data will be
request.all() : { "users": [ { "name": "John Doe" } ] }
request.allFiles(): { "users": [ { "avatar": <File> } ] }
And to running the validation, these data pieces will need to be merged to make sure it pass the rules.
Unfortunately, following AdonisJS's author idea that deep merge will affect to the performance of the framework. Therefore, shallow merge is used to combine them and it looks like this
data = {
...body,
...files,
}
And you know what happened. After the merge, user item only has avatar property.
Solution
As the author suggestion in the comment about, I've change the way to validate the data by perform deep merge data by using lodash merge and use AdonisJS standalone validator to validate the merged data
import lodashMerge from 'lodash/merge'
import { validator } from '@ioc:Adonis/Core/Validator'
...
allData = lodashMerge({}, request.all(), request.allFiles())
params = await validator.validate({
data: allData,
schema: schema.create({
users: schema.array().members(
schema.object().members({
name: schema.string({ trim: true }),
avatar: schema.file({
size: '10mb',
extnames: ['jpg', 'heic']
}),
})
),
}),
})
And that's how I got the params as same as the way it's submitted.
Readers, let me know if you can see any other way to resolve this issues.
Thanks for reading.
Top comments (0)