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 valuenull- Describes nullboolean- Describes booleansnumber: Describes numbersstring: Describes stringsbinary: Describes binariesset: Describes sets of eithernumber,string, orbinaryelementslist: Describes lists of elements of the same typetuple: Describes tuples with a given list of elements (finite index-schema pairs)item: Describes items with a given list of attributes (finite key-schema pairs) - Should be at the root ofEntityschemasmap: Describes maps - Similar toitems, but can be nested within other schemasrecord: Describes a different kind of maps - Records differ frommapsas 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 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)
Portabilityβ
Schemas are portable: They can be imported from or exported to Zod and JSON Schema with type-inference preserved. The transpilation itself is type-safe, so type inference holds in both directions.
Zodβ
The ZodSchemer action transpiles a DynamoDB-Toolbox schema into a Zod schema (for parsing or formatting):
import { ZodSchemer } from 'dynamodb-toolbox/schema/actions/zodSchemer'
const zodParser = pokemonSchema.build(ZodSchemer).parser()
const parsed = zodParser.parse(input)
// => TransformedValue<typeof pokemonSchema>
Conversely, the fromZodSchema util derives a DynamoDB-Toolbox schema from a Zod schema:
import { z } from 'zod'
import { fromZodSchema } from 'dynamodb-toolbox/schema/actions/fromZodSchema'
const zodSchema = z.object({
pokemonId: z.string(),
level: z.number()
})
const pokemonSchema = fromZodSchema(zodSchema)
JSON Schemaβ
The JSONSchemer action transpiles a DynamoDB-Toolbox schema into a standard JSON Schema (of its formatted value) β useful for OpenAPI specs, form generation or LLM/MCP tool definitions:
import { JSONSchemer } from 'dynamodb-toolbox/schema/actions/jsonSchemer'
const jsonSchema = pokemonSchema
.build(JSONSchemer)
.formattedValueSchema()
// =>
// {
// type: 'object',
// properties: {
// pokemonId: { type: 'string' },
// level: { type: 'number' }
// },
// required: ['pokemonId', 'level']
// }
DTOβ
You can also serialize a schema to a portable SchemaDTO and rebuild it later with fromDTO.