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

Thoughts on something like any.meta(obj)? #241

Closed
joshuafcole opened this issue Apr 10, 2014 · 10 comments · Fixed by #311
Closed

Thoughts on something like any.meta(obj)? #241

joshuafcole opened this issue Apr 10, 2014 · 10 comments · Fixed by #311
Assignees
Labels
feature New functionality or improvement
Milestone

Comments

@joshuafcole
Copy link

This is conceptually similar to any.tags(), any.notes(), and any.description(), but allows the storage of an object rather than a string. This is valuable because, besides annotating the schemas, it allows us to build modules on Joi that provide additional functionality. Example use case:

var schema = {
  _id: Joi.number().integer().meta({index: {unique: true, sparse: true}}),
  name: 'Margaret'
};

// Registers schema as the validator for person models, and
// extracts indexing information for each field from the metadata on each field.
myDBAdapter.model('Person', schema);

This can currently be accomplished using tags(), but it requires string parsing and complicates the logic of actually retrieving the metadata. E.g.

var schema = {
  _id: Joi.number().integer().tags(['index:unique', 'index:sparse']),
  name: 'Margaret'
};

The benefit of an any.meta() is similar to that of the existing description functions -- the metadata is stored consistently and doesn't need to worry about clobbering / being clobbered by Joi's moving parts.

Cheers,
Josh

@hueniverse
Copy link
Contributor

How do you expect to extract this information afterwards?

@joshuafcole
Copy link
Author

Couple of options. The first (in keeping with tags and notes) would be to just make it an attribute on the object returned by describe(). Another might be calling meta() with an arity of 0 to retrieve the meta object (which could also be applied to the other functions for consistency).

I think the idea itself is valuable, but I'm not particularly opinionated on how it should be implemented. If you think it's useful but not critical I can try my hand at the implementation once a pattern is settled on.

@hueniverse
Copy link
Contributor

I am not a fan of functions returning completely different types of data based on arguments count. We can use describe() but it's an expensive call for runtime since it builds the full internal structure. More ideas?

@joshuafcole
Copy link
Author

Hrmm, in that case, we can still do:

  • Something obvious but clunky, like getMeta()
  • Use an accessor method to expose a .metadata attribute or some such
  • Add a describe() analog (or perhaps parameterize describe() with a shallow=false parameter) that only describes the top level schema rather than walking the entire structure.

@hueniverse
Copy link
Contributor

The problem is that if you put meta on nested keys, it becomes hard to get to that without building the entire description tree. I need to think about it some more.

@Bartvds
Copy link
Contributor

Bartvds commented Apr 26, 2014

+1 on a shallow describe analog to access the info for a single schema without recursion.

@joshuafcole
Copy link
Author

I think a shallow describe option makes a lot of sense. It allows you to determine whether or not you care about metadata on nested keys. The cost of describe I assume is primarily in building the full tree, so the most direct solution is to allow the end user to choose whether or not they require that.

@joshuafcole
Copy link
Author

I'm trying my hand at implementing this now since I require the functionality. @hueniverse Would you prefer that meta be cumulative (as tags is) through extension, or that the last call to meta overwrite the previous ones? I'll implement that latter first since it's marginally simpler and seems like an edge case, but I'll defer to whatever you prefer in the PR.

joshuafcole pushed a commit to joshuafcole/joi that referenced this issue May 9, 2014
joshuafcole pushed a commit to joshuafcole/joi that referenced this issue May 9, 2014
joshuafcole pushed a commit to joshuafcole/joi that referenced this issue May 9, 2014
@joshuafcole
Copy link
Author

Also, in the clone method, would you like meta to be shallow/deep copied? Or is a direct reference acceptable?

joshuafcole pushed a commit to joshuafcole/joi that referenced this issue May 9, 2014
joshuafcole pushed a commit to joshuafcole/joi that referenced this issue May 9, 2014
@hueniverse hueniverse added this to the 4.3.0 milestone May 22, 2014
@hueniverse hueniverse self-assigned this May 22, 2014
@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

Successfully merging a pull request may close this issue.

3 participants