koajs / joi-router

Configurable, input and output validated routing for koa
MIT License
450 stars 96 forks source link

default query string options do not work for empty query string #62

Open piotr-s-brainhub opened 6 years ago

piotr-s-brainhub commented 6 years ago

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

piotr-s-brainhub commented 6 years ago

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;
  },
};
piotr-s-brainhub commented 6 years ago

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' }
});
alldayalone commented 3 years ago

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();
};