Amazon DynamoDB
RetrieveMultiple
8 samples, from the least code that works to complete workflows.
What a RetrieveMultiple does
| Rule | On DynamoDB |
|---|---|
| A query | Needs the partition: Equal conditions on the attributes of the table's partition key, or of an index's (ARX picks it, or IndexName names it). Conditions on the sort key's attribute narrow the range; the others filter what was read |
| Joins | ARX8001: in the single-table design, related items share a partition and QueryPartitionAsync reads them together |
| Paging | By the PagingCookie each page returns; HasNextPage is exact. A page number above 1 and a total count are ARX8001 |
| Paging cookies | Sealed by default (encrypted and authenticated: a client can neither read nor change one), with a random key of the process unless PagingCookieKey is set. Several instances, or cookies across a restart: the same PagingCookieKey everywhere, or a cookie is ARX1001 on the other. PagingCookieProtection can be Signed or Plain (Advanced 4) |
| No partition | ARX8001, unless new ArxDynamoReadOptions { AllowScan = true }: a scan reads, and pays for, the whole table |
| Patterns | Contains and BeginsWith only with CaseSensitivePatterns = true (DynamoDB compares case-sensitively); EndsWith and Like are ARX8001 |
| Order | By the sort key only, ascending or descending |
| Aggregates | A Count alone (DynamoDB counts, Select COUNT); other aggregates and grouping are ARX8001 |
| Indexes | Eventually consistent: a write shows in an index a moment later (ARX reads an index without ConsistentRead, which DynamoDB refuses there) |
| Sharded partitions | Every shard is queried and the results merged in sort key order, paged by one cookie |
A loop over the pages that must also run on the SQL providers ends each page with
query.PageInfo = query.PageInfo.Next(page) and stops on null (from 0.1.0-preview.5): the samples pass the cookie on,
which is DynamoDB's way, and on PostgreSQL, SQL Server or MySQL, which return no cookie, that loop reads the first page
again.
The samples
Basics
The least code that works.
1Retrieve many recordsProgressiveRead many items with ArxQueryExpression, in three scenarios: a customer's orders, newest first and filtered, a range of the sort key, and a query DynamoDB can't answer without a scan.
Page through a partition with paging cookies, in three scenarios: the first page, the next pages from the cookie, and a page number, which DynamoDB can't jump to.
Real cases
What an application does: a small CRM and product catalogue.
1A customer and its orders in one requestProgressiveThe single-table design's reason to exist: a customer and its orders in one request, in two scenarios: the whole item collection, and a page of it.
The operations screen: every open order, across customers, through the GSI1 index, in three scenarios: by status, by status and a date range, and the count of open orders.
A search endpoint whose sort and filter fields come from the request, attacked three ways: expression syntax in a filter name, an index name that isn't in the model, and a partition value written to read every customer; then the honest search.
Advanced cases
Dependency injection, transactions, batch scopes and setting the service up.
1Scan when you mustAdvancedReads with no partition, in three scenarios: refused by default, a scan you allow, and a text search, which needs you to say that DynamoDB compares case-sensitively.
A security check around searches (SecurityGuard), in three scenarios: a normal search, an attack in the requested columns that is logged, and repeated attacks that block the user.
Protect the paging cookies your API hands to clients, in three scenarios: sealed by default, one key shared by every instance of the application, and plain cookies when you choose them.