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
typeof the secondary index ("local"or"global") - For global secondary indexes, the
partitionKeyof the index (similar to the mainpartitionKey) - If present, the
sortKeyof 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.