Skip to main content
Version: v2

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
})
info

Note that you can provide a map schema to the Entity constructor, although only its attributes will be 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 binary elements
  • 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 Entity schemas
  • map: Describes maps - Similar to items, but can be nested within other schemas
  • record: Describes a different kind of maps - Records differ from maps as they have a non-explicit (potentially infinite) range of keys, but with a single value type
  • anyOf: Describes a finite union of possible schemas
info

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

Schemas are a standalone feature of DynamoDB-Toolbox (you can use them separately to parse and format data for instance) and might even be moved into a separate library one day.

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' })
info

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')
info

☝️ Checking a schema will also freeze 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)