Joi: Casting to string fails in all cases

Created on 26 Mar 2016  路  9Comments  路  Source: sideway/joi

https://github.com/hapijs/joi/blob/master/lib/string.js#L64-L65

    if (typeof value === 'string' &&
        options.convert) {
...

If you have a schema that declares an option as a string, but you validate it against something like a number, it throws a validation error instead of casting the number to a string. I assume this decision was made on purpose, but it presents problems either way you do it.

In my case, I was using minimist to process command line arguments; minimist took an argument I provided as a number, and converted it TO a number. I know I can change this behavior, but I was hoping to leave the responsibility for coercion completely to my Joi schema. This means that I would get random failures when they aren't necessarily desired, if minimist decides that the value shouldn't be a string.

I can see the potential for error, here: pretty much anything can be coerced to a string, which means that you could wind up with a lot of potential error cases, especially since 'convert' is true by default. It would be nice if you could specify an option that says "no, I really do want anything to become a string". I mean, command line arguments are all strings to start with, so it is a bit nasty to have to parse my entire Joi schema to find the string arguments and convey that back to minimist to make it not convert things, or specify manually every potential option to minimist and have it just keep everything as a string, etc.

What are the chances of such an option making it into the codebase?

feature

Most helpful comment

My problem with casting anything to a string is that it is a very odd use case. The reason to cast strings to other values is obvious - data coming from form-encoded sources (payload, query) has to be casted because it is type-less. But if the data comes in with a type (json), forcing it seems odd. To me it is the sign of a poorly designed system.

All 9 comments

I'm running into this problem as well. Being able to convert between numbers and strings with joi schemas would be immensely useful in my case.

I agree with @myndzi that {convert: true} should not coerce all types to a string - I think just
number <---> string type coercion would be sufficient.

We were surprised by this as well:

If the following works:

var joi = require("joi");

var schema = joi.object().keys({
  a: joi.number()
});

joi.validate({ a: "1" }, schema, { convert: true });

It seems reasonable to conclude that this should also work, but it does not:

var joi = require("joi");

var schema = joi.object().keys({
    a: joi.string()
});

joi.validate({ a: 1 }, schema, { convert: true });

The error returned:

child "a" fails because ["a" must be a string]

Are you open to a PR to patch this or was the convert feature intended to be one-way only?

Converting strings to values is a well defined process. Converting some values to strings is not. So we need to be more selective when to apply this. Numbers to strings seems safe.

If we would do this, it should be documented what types do convert to a string

@hueniverse @AdriVanHoudt would it be acceptable to start only with Numbers (in addition to the current String behavior)? Then, if other use cases beyond those identified here crop up, we could evaluate those similarly case-by-case? I am happy to help if you'd like.

hmm I can see this being a can of worms :P since like @hueniverse said, casting to a number is defined, to a string not so much. I would be ok starting with number to string if @Marsup agrees with it

My problem with casting anything to a string is that it is a very odd use case. The reason to cast strings to other values is obvious - data coming from form-encoded sources (payload, query) has to be casted because it is type-less. But if the data comes in with a type (json), forcing it seems odd. To me it is the sign of a poorly designed system.

Sorry for my silence on this one, I've been thinking about it on and off, and I think everyone will have its own definition of converting something to a string. As it feels like a Pandora's box to this library, I'd rather let an extension pioneer the idea, and if everyone comes to an agreement as to how it should work, eventually integrate it into joi, so that's a soft no for now.

This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Taxi4you picture Taxi4you  路  3Comments

longweiquan picture longweiquan  路  3Comments

alekbarszczewski picture alekbarszczewski  路  3Comments

leore picture leore  路  4Comments

PaunPrashant picture PaunPrashant  路  3Comments