UpdateAttributesCommand
Performs a UpdateAttributes Operation on an entity item. Similar to UpdateItemCommand
except than deep attribute updates are non-partial:
import { UpdateAttributesCommand } from 'dynamodb-toolbox/entity/actions/updateAttributes'
const updateAttributesCommand = PokemonEntity.build(
UpdateAttributesCommand
)
const params = updateAttributesCommand.params()
await updateAttributesCommand.send()
Requestβ
.item(...)
β
(required)
The attributes to update, including the key:
import { UpdateAttributesCommand } from 'dynamodb-toolbox/entity/actions/updateAttributes'
await PokemonEntity.build(UpdateAttributesCommand)
.item({
pokemonId: 'pikachu1',
level: 12,
...
})
.send()
You can use the UpdateAttributesInput
type to explicitly type an object as a UpdateAttributesCommand
item object:
import type { UpdateAttributesInput } from 'dynamodb-toolbox/entity/actions/updateAttributes'
const item: UpdateAttributesInput<typeof PokemonEntity> = {
pokemonId: 'pikachu1',
level: 12,
...
}
await PokemonEntity.build(UpdateAttributesCommand).item(item).send()
UpdateAttributesInput
differs from PutItemInput
as the root attributes are partially required β except for always
required attributes without defaults or links β and benefit from an extended syntax that reflects the capabilities of DynamoDB.
It also differs from UpdateItemInput
as deep attributes (e.g. lists
, maps
and records
) are always completely overridden by default.
Root attributesβ
Root attributes, wether flat or deep, benefit from the same syntax as the UpdateItemCommand
command:
- $remove
- $get
- Flat attributes
- Numbers
- Sets
// π Extended syntax is taken from `UpdateItemCommand`
import { $remove } from 'dynamodb-toolbox/entity/actions/update'
await PokemonEntity.build(UpdateAttributesCommand)
.item({
pokemonId: 'pikachu1',
// π clear 'statusEffect' from pokemon
statusEffect: $remove()
})
.send()
import { $get } from 'dynamodb-toolbox/entity/actions/update'
await PokemonEntity.build(UpdateAttributesCommand)
.item({
...
level: 42,
// π fill 'previousLevel' with current 'level'
previousLevel: $get('level')
})
.send()
await PokemonEntity.build(UpdateAttributesCommand)
.item({
...
// π Set fields to desired values
isLegendary: true,
nextLevel: 42,
name: 'Pikachu',
binEncoded: new Uint8Array(...),
skills: new Set(['thunder'])
})
.send()
import {
$add,
$subtract,
$get
} from 'dynamodb-toolbox/entity/actions/update'
await PokemonEntity.build(UpdateAttributesCommand)
.item({
...
// π lose 20 health points
health: $subtract($get('health'), 20),
// π gain 1 level
level: $sum($get('level', 0), 1),
// ...similar to
level: $add(1)
})
.send()
import {
$add,
$delete
} from 'dynamodb-toolbox/entity/actions/update'
await PokemonEntity.build(UpdateAttributesCommand)
.item({
...
skills: $add(new Set(['thunder', 'dragon-tail'])),
types: $delete(new Set(['flight']))
})
.send()
Deep attributesβ
In the case of deep attributes (e.g. lists
, maps
and records
), updates are complete by default:
// π Complete overrides
await PokemonEntity.build(UpdateAttributesCommand).item({
...
// Resets list
skills: ['thunder'],
// Removes all other map attributes
some: {
deep: {
field: 'foo',
otherField: 42
}
},
// Removes all other record keys
bestSkillByType: {
electric: 'thunder'
}
})
Lists benefit from additional $append
and $prepend
extensions, which can use references:
import {
$append,
$prepend
} from 'dynamodb-toolbox/entity/actions/update'
PokemonEntity.build(UpdateAttributesCommand).item({
...
skills: $append(['thunder', 'dragon-tail']),
levelHistory: $append($get('level')),
types: $prepend(['flight']),
})
$append
and $prepend
are upserts: they create a new list if the attribute is missing from the item.
.options(...)
β
Provides additional options:
await PokemonEntity.build(UpdateAttributesCommand)
.item(...)
.options({
returnValues: 'UPDATED_OLD',
capacity: 'TOTAL',
...
})
.send()
The options are the same as the UpdateItemCommand
action options. Check the dedicated section for more details.
Responseβ
The data is returned using the same response syntax as the DynamoDB UpdateItem API, with an additional ToolboxItem
property, which allows you to retrieve the item generated by DynamoDB-Toolbox:
const { ToolboxItem: generatedPokemon } =
await PokemonEntity.build(UpdateAttributesCommand)
.item(...)
.send()
// π Great for auto-generated attributes
const modifiedTimestamp = generatedPokemon.modified
If present, the returned attributes are formatted by the Entity.
You can use the UpdateAttributesResponse
type to explicitly type an object as an UpdateAttributesCommand
response object:
import type { UpdateAttributesResponse } from 'dynamodb-toolbox/entity/actions/updateAttributes'
const response: UpdateAttributesResponse<
typeof PokemonEntity,
// π Optional options
{ returnValues: 'ALL_OLD' }
// π Typed as PokemonΒ | undefined
> = { Attributes: ... }