dynamodb-toolbox icon indicating copy to clipboard operation
dynamodb-toolbox copied to clipboard

Add schema support for maps

Open jeremydaly opened this issue 6 years ago • 5 comments

Only top level schemas are supported. By adding support for nested maps, we could enforce types and provide a cleaner way to update data maps. This should be optional, falling back to the current dot notation for unmapped structures.

Proposed implementation

const MyModel = new Model('MyModel',{
  // Specify table name
  table: 'my-dynamodb-table',

  // Define partition and sort keys
  partitionKey: 'pk',
  sortKey: 'sk',

  // Define schema
  schema: {
    pk: { type: 'string', alias: 'id' },
    sk: { type: 'string', hidden: true },
    someMap: {
      type: 'map' ,
      schema: { // $ shorthand
        title: 'string', // support string-based type declarations
        count: { type: 'number', default: 10 }, // support scalars with defaults and other options
        someList: { type: 'list' },
        someNestedMap: { // Supported nested maps with schemas
          type: 'map',
          schema: { ... }
        }
      } 
    }
  }
})

This would enable support for schema validation as well as partial updates.

jeremydaly avatar Nov 29 '19 23:11 jeremydaly

Any update on this one? Would be such a great feature as otherwise we lose all the awesome aliasing features in the deeper nested maps 😢.

mfbx9da4 avatar Nov 13 '20 10:11 mfbx9da4

It would be handy to support list schema too. For eg.

someList: { type: 'list', schema: { name: 'string', enrolled: 'boolean' } }

the expected input for this would be:

const list = [{ name: 'foo', enrolled: true}, { name: 'bar', enrolled: false}]

adikari avatar Feb 19 '21 01:02 adikari

I am happy to create the PR for this. Let me know.

adikari avatar Feb 19 '21 02:02 adikari

+1 to this feature, typing on maps would be super useful

garretcharp avatar Oct 06 '21 21:10 garretcharp

To add to this being able to alias to a non-nested field would be super useful it doesnt seem like its possible right now?

I have here an example "Giveaway" model that has a winners object with the current winner and past winners (if any). And would like to alias winners.current to "winner", not sure if that is possible:

const giveaway = new Entity({
  table,
  name: 'Giveaway',
  attributes: {
    id: { partitionKey: true, prefix: 'Giveaway#' },
    sk: { sortKey: true, default: 'Giveaway#', hidden: true },

    winner: { type: 'map', dependsOn: 'winners', default: (item) => item.winners.current, save: false },
    winners: { type: 'map', default: { current: {}, pastWinners: [] } }
  }
})

Whenever I parse an item the winners.current value is correct, however, the default function for winner never gets called so the "winner" object is not populated. I assume I could probably put save to true and it would work via duplicating the value but not ideal.

garretcharp avatar Oct 07 '21 00:10 garretcharp