Vulcan
Vulcan copied to clipboard
New Feature: createSchema()
I'd like to add a new createSchema()
function that would basically act as a thin wrapper around new SimpleSchema()
.
The main reason would be to get rid of the confusing foo.$
SimpleSchema syntax for array items. Instead we could specify type
and itemType
and createSchema()
would take care of creating the new foo.$
field with the correct itemType
schema.
As @doronrk suggested, this could eventually also help dissociate the database and API fields, for example if you wanted fields that exist in your API but not in your SimpleSchema (currently every field has to be included in your SimpleSchema schema whether it actually lives in the database or not).
This might be basic, but how does the createSchema wrap?
e.g. how would I change my nested schema for 'articles' (articles.$
)?
My guess is you remove articles.$
, something like in the before/after code below. My confusion is that I don't know where I'd have to put createSchema
, but I think I understand the concept. Overall it makes sense for me, simplifies it and makes it more intuitive
Before:
articles: {
type: Array,
canRead: ['guests'],
group: articleGroup,
optional: true,
blackbox: true,
canCreate: ['members'],
canUpdate: ['members'],
},
'articles.$': {
canRead: ['guests'],
type: articleSchema,
},
After:
articles: {
type: Array,
canRead: ['guests'],
group: articleGroup,
optional: true,
blackbox: true,
canCreate: ['members'],
canUpdate: ['members'],
createSchema:articleSchema <<<<<<<<<??
}
Almost, it's:
articles: {
type: Array,
canRead: ['guests'],
group: articleGroup,
optional: true,
blackbox: true,
canCreate: ['members'],
canUpdate: ['members'],
itemType:articleSchema <<<<<<<<<
}
And createSchema
is then called transparently in the background (inside createCollection
) to transform that into the two separate fields.
Actually it'll be
arrayItem: { type: String }
instead of
itemType: String
This way you can just specify any property that would normally go on the array item in there and it simplifies the logic.
As @doronrk suggested, this could eventually also help dissociate the database and API fields
It's probably worth digging into this further. For example, we could imagine a new format for schemas along these lines:
const schema = {
database: {
foo: {...},
bar: {...}
},
api: {
bar: {...},
baz: {...},
}
}
Or alternatively maybe:
const schema = {
foo: { database: true, api: false, ...},
bar: { database: true, api: true, ...},
baz: { database: false, api: true, ...},
}
The idea being that the API-only fields would be removed from the SimpleSchema object; and that the database-only fields would have no chance of being made accessible through the API by mistake.