[translate][suggestion] Use chaining instead of passing as param
itaditya opened this issue · comments
I saw the code snippet
const userSchema = schema({
name: String,
email: String,
}, translate({
email: "emails.0",
}));
One thing that bugged me was the passing of translate
to schema
function as a positional parameter. From my personal experience I have found that this method doesn't do well in long term. I suggest using chaining method to extend the functionality like so -
const userSchema = schema({
name: String,
email: String,
}).translate({
email: "emails.0",
})
Libraries like moment, jQuery all use this pattern, I can dig up some solid advantages if you like
I see value on that, but I'm not sure if I like it.
The first problem I see is: how can someone build a plugin for schm
without adding it to the library itself (I mean, adding the method to the chain)?
The answer could be, instead of adding methods directly do the chain, to have a .plugin
method where you pass the plugin as an argument:
schema({...}).plugin(translate({...})).plugin(query({...}))
But I don't know if that's really better than what we have today, which is, in my opinion, more straightforward:
schema({...}, translate({...}), query({...}))
The schema
method is intended to be kind of compose
. Actually, that was its name when I was first writing the library.
You can think of schema
this way (and this is actually possible 😄: https://runkit.com/diegohaz/schm-schm-schm-schm):
schema(schema(), schema(schema(schema()), schema()))
The literal object you pass to schema
is actually a shorthand to this:
schema(group({...}))
group
returns a schema, translate
returns a schema. So everything still makes sense. Maybe what we need to do is to make it more clear in the docs.
That said, that's extremely easy to create a custom schema
with chainable methods:
const schm = require('schm')
const translate = require('schm-translate')
const withTranslate = prevSchema => prevSchema.merge({
translate(...args) {
return schm(this, translate(...args))
}
})
const schema = params => schm(params, withTranslate)
const userSchema = schema({
name: String,
email: String,
}).translate({
email: "emails.0",
})
See the above snippet working: https://runkit.com/diegohaz/chainable-schm