Table
Each Table instance describes the configuration of a deployed DynamoDB Table: Its name, primary key, secondary indexes, and more.
import { Table } from 'dynamodb-toolbox/table'
const PokeTable = new Table({
...
})
The configuration provided to the Table
constructor must match your resources. But DynamoDB-Toolbox does NOT hold the responsibility of actually deploying them. This should be done by other means, like the AWS CLI, Terraform or Cloudformation.
Constructorβ
The Table
constructor takes a single parameter of type object
and accepts the following properties:
documentClient
β
As mentioned in the Getting Started section, DynamoDB-Tooblox is an abstraction layer over the Document Client, but it does not replace it. A DocumentClient
instance is explicitly needed for commands to interact with DynamoDB:
// From peer dependencies
import { DynamoDBClient } from '@aws-sdk/client-dynamodb'
import { DynamoDBDocumentClient } from '@aws-sdk/lib-dynamodb'
const dynamoDBClient = new DynamoDBClient()
const documentClient = DynamoDBDocumentClient.from(
dynamoDBClient,
{
marshallOptions: {
// Specify your client options as usual
removeUndefinedValues: true,
convertEmptyValues: false
...
}
}
)
const PokeTable = new Table({
documentClient,
...
})
You can also set it later in the code (but beware that commands fail if no client has been provided):
const PokeTable = new Table(...)
// Later in the code
const documentClient = ...
PokeTable.documentClient = documentClient
name
β
A string
(or function returning a string
) that matches the name of your DynamoDB table:
- Fixed
- From env
- Getter
const PokeTable = new Table({
name: "poke-table",
...
});
const PokeTable = new Table({
name: process.env.POKE_TABLE_NAME,
...
});
const PokeTable = new Table({
// π Only executed at command execution
name: () => process.env.POKE_TABLE_NAME,
...
});
You can also provide it through command options β which is useful for multitenant apps β but beware that commands fail if no table name has been provided:
const PokeTable = new Table({
// Omit `name` property
documentClient,
...
})
// Scan tenant table
const { Items } = await PokeTable.build(ScanCommand)
.options({ tableName: tenantTableName })
.send()
partitionKey
β
(required)
The partition key attribute name and type of your DynamoDB table:
- String
- Number
- Binary
const MyTable = new Table({
...,
partitionKey: {
name: "pokemonId",
type: "string",
}
})
const MyTable = new Table({
...,
partitionKey: {
name: "pokemonId",
type: "number",
}
})
const MyTable = new Table({
...,
partitionKey: {
name: "pokemonId",
type: "binary",
}
})
sortKey
β
If present, the sort key attribute name and type of your DynamoDB table:
const MyTable = new Table({
...,
sortKey: {
name: "level",
type: "number",
}
})
indexes
β
An object that lists the secondary indexes of your DynamoDB Table.
Secondary indexes are represented as key-value pairs, keys being the index names, and values containing:
- The
type
of the secondary index ("local"
or"global"
) - For global secondary indexes, the
partitionKey
of the index (similar to the mainpartitionKey
) - If present, the
sortKey
of the index (similar to the mainsortKey
)
- Global Index
- Global Index (+ sort key)
- Local Index
const MyTable = new Table({
...,
indexes: {
byTrainerId: {
type: 'global',
partitionKey: { name: 'trainerId', type: 'string' }
}
}
})
const MyTable = new Table({
...,
indexes: {
byTrainerId: {
type: 'global',
partitionKey: { name: 'trainerId', type: 'string' },
sortKey: { name: 'level', type: 'number' }
}
}
})
const MyTable = new Table({
...,
indexes: {
byLevel: {
type: 'local',
sortKey: { name: 'level', type: 'number' }
}
}
})
When whitelisted, the projected attributes of a secondary index should include the Table
's entity attribute for a more performant formatting of the returned data.
entityAttributeSavedAs
β
DynamoDB-Toolbox tags your data via an internal and hidden entity
attribute. Any write command automatically sets its value to the corresponding Entity
name.
To allow for appropriate formatting when fetching multiple items of the same Table
in a single operation (like Queries or Scans), the key of this attribute must be the same accross all of its items, so it must be set at the Table
level.
Its default value is _et
, but it can be renamed through the entityAttributeSavedAs
argument:
const MyTable = new Table({
...
// π defaults to '_et'
entityAttributeSavedAs: '__entity__',
});
βοΈ This property cannot be updated once your Table has its first item (at least not without a data migration first), so choose wisely!
meta
β
Attaches metadata to the Table
(as an object property).
The meta
object can include a title
and description
, both of which must be strings. Additional fields can be of any type:
const MyTable = new Table({
...
meta: {
title: 'Pokedex',
description: 'An Awesome Table for development use',
other: { field: 'of any type' }
}
})
// π Directly access/modify metadata
console.log(MyTable.meta)
MyTable.meta.foo = 'A new field'
Although optional, the meta property can be helpful in scenarios like describing a MCP Server or synchronizing with DynamoDB-Toolshack.
Building Table Actionsβ
To allow for extensibility, better code-splitting and lighter bundles, Tables
only expose a .build(...)
method which acts as a gateway to perform Table Actions:
import { ScanCommand } from 'dynamodb-toolbox/table/actions/scan'
const { Items } = await PokeTable.build(ScanCommand).send()
If you don't mind large bundle sizes, you can still use the EntityRepository
actions that expose all the others as methods.