joi-router
joi-router copied to clipboard
default query string options do not work for empty query string
OS: Max OS X 10.12.2 Node version: 8.6.0 npm version: 5.2.0 koa version: 2.4.1 koa-joi-router version: 5.0.0 joi version: 9.2.0
I have the following route:
module.exports = {
method: 'get',
path: '/',
validate: {
query: Joi.object().keys({
search: Joi.string(),
sort: Joi.object().default({ 'name': 1 }),
}),
},
handler: async (ctx) => {
const { sort } = ctx.query;
console.log(sort);
ctx.status = 200;
},
};
The actual behavior:
when I specify a query string ex. ?search=foo, I get the correct default value for sort parameter, however for no query string I get undefined
The expected behavior:
even for no query string, the sort parameter should have { 'name': 1 } as default value
This doesn't work as well:
module.exports = {
method: 'get',
path: '/',
validate: {
query: Joi.object({
search: Joi.string(),
sort: Joi.object().default({ 'name': 1 }),
}).optional(),
},
handler: async (ctx) => {
const { sort } = ctx.query;
console.log(sort);
ctx.status = 200;
},
};
It's because Joi needs to obtain a query object
const Joi = require('joi');
const schema = {
query: Joi.object({
search: Joi.string(),
sort: Joi.object().default({ 'name': 1 }),
}).optional(),
foo: Joi.string(),
};
const object = {
foo: 'foo',
query: {},
};
Joi.validate(object, schema, (err, value) => {
console.error(err);
console.log(value); // { foo: 'foo', query: { sort: { name: 1 } } }
});
const Joi = require('joi');
const schema = {
query: Joi.object({
search: Joi.string(),
sort: Joi.object().default({ 'name': 1 }),
}).optional(),
foo: Joi.string(),
};
const object = {
foo: 'foo',
};
Joi.validate(object, schema, (err, value) => {
console.error(err);
console.log(value); // { foo: 'foo' }
});
I also faced this issue but in my case, the problem was caused by koa-qs package. Internally it uses descriptors set/get to manage ctx.request.query. I replaced it with my own simple middleware and the issue resolved.
const qs = require('qs');
module.exports = (options) => async function queryParser(ctx, next) {
ctx.request.query = qs.parse(ctx.request.querystring, options);
await next();
};