Skip to main content
Version: v2

Entity

Entities represent a category of items in your Table.

An entity must belong to a Table, but a Table can contain items from several entities. DynamoDB-Toolbox is designed with Single Tables in mind, but works just as well with multiple tables and still makes your life much easier (e.g. for batch operations or transactions):

import { Entity } from 'dynamodb-toolbox/entity'
import { item } from 'dynamodb-toolbox/schema/item'
import { string } from 'dynamodb-toolbox/schema/string'

const PokemonEntity = new Entity({
name: 'POKEMON',
table: PokeTable,
schema: item({
name: string(),
...
})
})
info

Note that you can provide a map schema to the Entity constructor:

import { Entity } from 'dynamodb-toolbox/entity'
import { map } from 'dynamodb-toolbox/schema/map'
import { string } from 'dynamodb-toolbox/schema/string'

const PokemonEntity = new Entity({
name: 'POKEMON',
table: PokeTable,
schema: map({
name: string(),
...
})
})

See the Schema Section for more details.

Constructor

The Entity constructor takes a single parameter of type object and accepts the following properties:

name

(required)

A string that uniquely identifies your entity:

const PokemonEntity = new Entity({
name: 'POKEMON',
...
})
warning

DynamoDB-Toolbox automatically tags your items with their respective entity names (see Internal Attributes). While this can be opted out of, we strongly recommend keeping it enabled if you use Single Table Design.

☝️ A consequence is that name cannot be updated once your Entity has its first items* (at least not without a data migration first), so choose wisely!

schema

(required)

The schema of the Entity. See the Schema Section for more details on how to define schemas.

table

(required)

The Table of the Entity.

DynamoDB-Toolbox must check that an entity schema matches its Table primary key somehow. In simple cases, both schemas can simply fit:

Examples
const PokeTable = new Table({
partitionKey: { name: 'pk', type: 'string' },
sortKey: { name: 'sk', type: 'number' },
...
})

const PokemonEntity = new Entity({
table: PokeTable,
schema: item({
pk: string().key(),
sk: number().key(),
...
}),
})

computeKey

(potentially required, depending on schema)

...but using schemas that don't fit is OK.

In this case, the Entity constructor requires a computeKey function to derive the primary key from the Entity key attributes.

This can be useful for more complex cases like mapping several attributes to the same key:

Examples
const PokemonEntity = new Entity({
table: PokeTable,
schema: item({
// 👇 linked attributes should also be tagged as `.key()`
pokemonId: string().key(),
level: number().key(),
...
}),
// 🙌 Types are correctly inferred!
computeKey: ({ pokemonId, level }) => ({
pk: pokemonId,
sk: level
})
})

entityAttribute

A boolean or object to customize the internal entity attributes (see Internal Attributes).

timestamps

A boolean or object to customize the internal created and modified attributes (see Internal Attributes).

Building Entity Actions

To allow for extensibility, better code-splitting and lighter bundles, Entities only expose a .build(...) method which acts as a gateway to perform Entity Actions:

import { GetItemCommand } from 'dynamodb-toolbox/entity/actions/get'

const { Item } = await PokemonEntity.build(GetItemCommand)
.key(key)
.send()
info

If you don't mind large bundle sizes, you can still use the EntityRepository actions that expose all the others as methods.