Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for union types in schemas. #197

Closed
joshuafcole opened this issue Mar 11, 2014 · 10 comments
Closed

Support for union types in schemas. #197

joshuafcole opened this issue Mar 11, 2014 · 10 comments
Assignees
Labels
feature New functionality or improvement
Milestone

Comments

@joshuafcole
Copy link

Hey folks, we really appreciate the work you've done with Joi. We use Hapi for our web server and are now looking to centralize all validation using a single set of Joi schemas for our mongo documents.

One of the few missing features that would be very useful is support for union types in schemas. This is useful in many cases -- all variants of providing an enumeration of valid types for a field. To give on example, it would be nice to implement a transparent reference function that can accept a value matching the schema or a value matching an identifying field in the schema, in the pattern:

function reference(schema, referenceField) {
  return Joi.any().validType(
    schema,
    schema[referenceField]
  );
}

var person = reference({
  id: Joi.number().integer(),
  name: Joi.string()
}, 'id');

var john = {
  id: 1,
  name: 'John Smith'
};

Joi.validate(john, person); // true
Joi.validate(1, person); // true

Which would return a type that would either accept a person value or a possible person id.

I'm hoping to graft Joi onto an ODM so we can use the same validation across the stack.

If there's anything I've missed that would let me already implement something similar please let me know. Otherwise, I'd be happy to do whatever I can to get some momentum behind this.

Cheers,
Josh

@joshuafcole
Copy link
Author

An alternate and cheaper to implement solution might be to provide a hook for manual validation, e.g.

var people = Joi.array().includes(person.validator(function(value) {
  return !(Joi.validate(value, Joi.number().integer()) &&
               Joi.validate(value, person));
}));

Of course, this design is much bulkier and less transparent.

@hueniverse
Copy link
Contributor

I am not following what you are asking for. All I see above is a person schema that the same as:

var id = Joi.number().integer();
var item = { id: id, name: Joi.string() };
var person = [id, item];

@joshuafcole
Copy link
Author

In the case of an array that works, but in the case of a single item it breaks down. array() was perhaps a bad choice there because includes() already does what I'd like. There's not currently a way (that I've been able to find) to do that for 1:1 relationships at all.

If we were adding that support anyway, it would be appealing to have a method like includes() for any which would act like allow() for types (rather than just an enumeration of values).

here's an example of the issue in the node repl:
http://pastebin.com/7f2Q5gSA

@hueniverse
Copy link
Contributor

person is not an array(), it is a list of alternative types allowed.

@joshuafcole
Copy link
Author

Apologies for the lack of clarity. I was hoping giving the example from the node session would help clear things up. What I meant to say was:

var person = [id, item];
Joi.array().includes(person);

Works great and is precisely the functionality that I want. However, Sometimes I want a 1:1 relationship

var class = {
  id: Joi.number().integer(),
  title: Joi.string(),
  people: Joi.array().includes(person), // works great
  instructor: person // does not work
};

Hopefully that helps?

@hueniverse
Copy link
Contributor

Why doesn't instructor work? It will match an id or item.

@joshuafcole
Copy link
Author

Perhaps I've made an error in the repl example I tried? Doing:

Joi.validate(7, [id, item]); // does not work
Joi.validate({id: 7, name: 'John'}, [id, item]); // also does not work.

Is there something I missed here? Apologies if I'm being dense.

@hueniverse
Copy link
Contributor

Works in 2.8. Try master.

@hueniverse hueniverse added this to the 2.8.0 milestone Mar 12, 2014
@hueniverse hueniverse self-assigned this Mar 12, 2014
@joshuafcole
Copy link
Author

Works great in 2.8, sorry for the trouble. Thanks!

@hueniverse hueniverse added feature New functionality or improvement and removed request labels Sep 19, 2019
@lock
Copy link

lock bot commented Jan 9, 2020

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.

@lock lock bot locked as resolved and limited conversation to collaborators Jan 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
feature New functionality or improvement
Projects
None yet
Development

No branches or pull requests

2 participants