Schema
Schemas are objects that describe the items and attributes of an Entity:
import { item } from 'dynamodb-toolbox/schema/item'
import { string } from 'dynamodb-toolbox/schema/string'
import { number } from 'dynamodb-toolbox/schema/number'
const pokemonSchema = item({
  pokemonId: string().key(),
  level: number().default(1),
  pokeType: string()
    .enum('fire', 'water', 'grass')
    .optional()
})
const PokemonEntity = new Entity({
  ...,
  schema: pokemonSchema
})
Note that you can provide a map schema to the Entity constructor, although only its attributes are kept (not its props):
import { map } from 'dynamodb-toolbox/schema/map'
const pokemonSchema = map({
  pokemonId: string().key(),
  ...
})
const PokemonEntity = new Entity({
  ...,
  schema: pokemonSchema
})
See the map documentation for more details.
Schemas can be imported by their dedicated exports, or through the schema or s shorthands. For instance, those declarations output the same schema:
// π More tree-shakable
import { string } from 'dynamodb-toolbox/schema/string'
const nameSchema = string()
// π Single import
import { schema, s } from 'dynamodb-toolbox/schema'
const nameSchema = schema.string()
const nameSchema = s.string()
Schema Typesβ
Available schema types are:
- any- Describes any value
- null- Describes null
- boolean- Describes booleans
- number: Describes numbers
- string: Describes strings
- binary: Describes binaries
- set: Describes sets of either- number,- string, or- binaryelements
- list: Describes lists of elements
- item: Describes items with a finite list of attributes, i.e. key-schema pairs - Should be at the root of- Entityschemas
- map: Describes maps - Similar to- items, but can be nested within other schemas
- record: Describes a different kind of maps - Records differ from- mapsas they have a non-explicit (potentially infinite) range of keys, but with a single value type
- anyOf: Describes a finite union of possible schemas
DynamoDB-Toolbox schema types closely mirror the capabilities of DynamoDB. See the DynamoDB documentation for more details.
Note that some schema types can be defined with other schemas. For instance, here's a list of string:
const nameSchema = string()
const namesSchema = list(nameAttr)
Schemas Propsβ
You can update schema properties by using dedicated methods or by providing input props.
The former provides a slick devX with autocomplete and shorthands, while the latter theoretically requires less compute time and memory usage (although it should be negligible):
// Using methods
const pokemonNameSchema = string().required('always')
// Using input props
const pokemonNameSchema = string({ required: 'always' })
Methods do not mute the origin schema, but return a new schema (hence the impact in memory usage).
The output of an schema method is also a schema, so you can chain methods:
const pokeTypeSchema = string()
  .required('always')
  .enum('fire', 'water', 'grass')
  .savedAs('t')
Validating Schemasβ
You can inspect a schema's properties at runtime and through its types via the props attribute:
const props = pokeTypeSchema.props
// => {
//  required: 'always',
//  enum: ['fire', 'water', 'grass'],
//  savedAs: 't'
// }
You can use the .check() method to verify the validity of a schema:
pokeTypeSchema.check()
// π With path for clearer error messages
pokeTypeSchema.check('pokeType')
βοΈ Checking a schema also freezes its props.
Using Schemasβ
To allow for extensibility, better code-splitting and lighter bundles, schemas only expose a .build(...) method which acts as a gateway to perform Schema Actions:
import { Parser } from 'dynamodb-toolbox/schema/actions/parse'
const pokeType = pokeTypeSchema.build(Parser).parse(string)