I have a problem of validation JSON that is passed in GET request query param as a serialized string.
What I need to achieve is to parse this serialized string back to JSON and validated it using Joi.
Example: Give is the JSON
{
limit: {size:10, page:0},
filter: {filter_by: 'foo', filter_val: 'foo', from: '1/1/2016',to: '1/1/2016' }
}
And this JSON is converted to query string is:
limit%5Bsize%5D=10&limit%5Bpage%5D=0&filter%5Bfilter_by%5D=foo&filter%5Bfilter_val%5D=foo&filter%5Bfrom%5D=1%2F1%2F2016&filter%5Bto%5D=1%2F1%2F2016
I need something like this to check:
validate: {
query: {
limit: Joi.someMethodToGetJsonFromString.object().keys({
size: Joi.number(),
page: Joi.number()
}
filter: Joi.someMethodToGetJsonFromString,.object().keys({
filter_by: Joi.string().valid(['option1', 'option2']),
filter_val: Joi.string(),
from: Joi.date(),
to: Joi.date(),
}
}
Is there anything in Joi that can help in this scenario, Or I need to write custom validation functions for it.
You'll want to swap out the query string parsing used because hapi doesn't support that format by default. It just uses Node's built in url
module to parse the URL which doesn't support complex encodings of query strings. You'll need to manually parse it using qs
, after that you can validate as normal.
You can set your custom parser via server.options.query.parser.
const Hapi = require('hapi');
const Joi = require('joi');
const Url = require('url');
const Qs = require('qs');
const server = new Hapi.Server();
server.connection({ port: 4000 });
const onRequest = function (request, reply) {
const uri = request.raw.req.url;
const parsed = Url.parse(uri, false); // skip the querystring parsing
parsed.query = Qs.parse(parsed.query); // parse it ourselves with qs
request.setUrl(parsed);
return reply.continue();
};
server.ext('onRequest', onRequest);
server.route({
config: {
validate: {
query: {
limit: Joi.object().keys({
size: Joi.number(),
page: Joi.number()
}),
filter: Joi.object().keys({
filter_by: Joi.string().valid(['option1', 'option2']),
filter_val: Joi.string(),
from: Joi.date(),
to: Joi.date(),
})
}
}
},
method: 'GET',
path: '/',
handler: function (request, reply) {
return reply('ok');
}
});
server.start((err) => {
if (err) {
throw err;
}
console.log('Started server');
});
This is discussed a little bit in the API docs under the request.setUrl()
method.
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