-
Notifications
You must be signed in to change notification settings - Fork 0
Adapter: Raw marker
See also (AWS JS SDK v3): DocumentClient marshalling. Vocabulary: Concepts.
Raw<T> is the v3 bypass marker for items already shaped for DynamoDB. It replaces the v2 Raw / DbRaw pair — there's just one marker now, since v3 always speaks DynamoDBDocumentClient.
import {Raw, raw} from 'dynamodb-toolkit';
const wrapped = raw({name: 'X', '-internal': 'kept'});
wrapped instanceof Raw; // true
wrapped.item; // {name: 'X', '-internal': 'kept'}When the Adapter sees a Raw<T> on post / put / patch:
-
prepareis skipped — your item flows verbatim intoItem/UpdateExpression. -
validateItemis skipped — caller asserts the item is already valid. -
Marshalling still runs —
lib-dynamodb's middleware encodesSet/Buffer/Numberetc. unconditionally.
await adapter.put(raw({name: 'X', '-search-name': 'x', '-t': 1}), {force: true});
// Written as-is; prepare/validateItem not calledAbout the --prefixed fields above. '-search-name' is a searchable mirror column that would normally be populated by the prepare hook from Expressions: Filter builder; '-t' is an author-convention technical field (the toolkit does not reserve it). The convention is only enforced by your own prepare / revive hooks — so bypassing prepare with raw() means you're bypassing the only thing that keeps the write self-consistent. You have to:
- Add every technical field your
reviveexpects to strip ('-t','-search-name','-search-climate', …), otherwise the round-trip read will come back with garbage fields visible or missing the markers your list queries depend on. - Match the exact naming convention your hooks use — rename
-t→_tin one place and bothprepareandrevivehave to change together, butraw()writes skip both and keep writing whatever you put in the object.
If you find yourself repeatedly mirroring prepare inside raw() call sites, the common fix is a small helper that calls adapter.hooks.prepare(item) explicitly and then wraps the result in raw(). See Concepts → technicalPrefix and managed fields for the broader pattern.
Pass {reviveItems: false} on a read method to receive Raw<TItem> instances:
const item = await adapter.getByKey({name: 'X'}, undefined, {reviveItems: false});
// item instanceof Raw === true; item.item is the raw record (technical fields visible)
const items = await adapter.getByKeys([{name: 'X'}, {name: 'Y'}], undefined, {reviveItems: false});
// items.forEach(i => i instanceof Raw)This is useful when piping data between adapters — the source adapter strips technical fields with its revive, then the destination adapter would have to re-add them via prepare. With Raw, you skip both round-trips.
| v2 | v3 |
|---|---|
new Adapter.Raw(item) |
raw(item) |
new Adapter.DbRaw(item) |
raw(item) (collapsed) |
Adapter.markAsRaw(item) |
raw(item) |
returnRaw: 'raw' / 'db-raw'
|
{reviveItems: false} |
-
Rawis a regular ES class; the brand is the class identity.x instanceof Rawis the check. - The
itemfield holds the verbatim wrapped value. Mutate it and the next write picks up the change. -
Rawworks for keys too —getByKey(raw({name: 'X'}))skipsprepareKey.
Start here
- Getting started
- Concepts
- Key and field design
- Compatibility
- Migration: v2 to v3
- SDK v2 to v3 cheat sheet
Guides
- Hierarchical data walkthrough
- Key expression patterns
- Multi-type tables
- Pagination
- Mass operation semantics
- URL schema design
Adapter
- Adapter
- Constructor options
- CRUD methods
- Mass methods
- Batch builders
- Hooks
- Raw marker
- Indirect indices
- Transaction auto-upgrade
Expression builders
Batch / transactions / mass / paths
REST surface
Framework adapters
Recipes
- Recipes index
- List records of a tier
- Per-tier sparse GSI markers
- Tier within a partition
- Reservation with auto-release
- Keys-only GSI, runtime projection
- Cascade subtree operations
- Querying subtrees with buildKey
- Filter URL grammar
- Text search
- Provisioning workflow
- Resumable mass operations
History