Vulcan icon indicating copy to clipboard operation
Vulcan copied to clipboard

New Feature: createSchema()

Open SachaG opened this issue 5 years ago • 4 comments

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).

SachaG avatar Feb 27 '20 10:02 SachaG

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 <<<<<<<<<??
    }

GraemeFulton avatar Feb 27 '20 11:02 GraemeFulton

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.

SachaG avatar Feb 28 '20 02:02 SachaG

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.

SachaG avatar Feb 28 '20 02:02 SachaG

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.

SachaG avatar Mar 02 '20 08:03 SachaG