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 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 valuenull
- Describes nullboolean
- Describes booleansnumber
: Describes numbersstring
: Describes stringsbinary
: Describes binariesset
: Describes sets of eithernumber
,string
, orbinary
elementslist
: Describes lists of elementsitem
: Describes items with a finite list of attributes, i.e. key-schema pairs - Should be at the root ofEntity
schemasmap
: Describes maps - Similar toitems
, but can be nested within other schemasrecord
: Describes a different kind of maps - Records differ frommaps
as they have a non-explicit (potentially infinite) range of keys, but with a single value typeanyOf
: 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 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)