-
Notifications
You must be signed in to change notification settings - Fork 875
Add Request Object Pattern for DynamoDB Document Model #4140
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: development
Are you sure you want to change the base?
Add Request Object Pattern for DynamoDB Document Model #4140
Conversation
wip wip implement sync update method and unit tests PutItemOperationRequest integration tests
1965390 to
fc6c71f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR introduces a Request Object Pattern for the DynamoDB Document Model API, modernizing the API surface by replacing overload-heavy methods with strongly-typed request objects. This change makes the API more extensible and aligns with modern SDK patterns by supporting expression-based syntax for operations like PutItem, UpdateItem, DeleteItem, GetItem, and Scan.
Key changes:
- Adds new request classes (
PutItemDocumentOperationRequest,UpdateItemDocumentOperationRequest,DeleteItemDocumentOperationRequest,GetItemDocumentOperationRequest,ScanDocumentOperationRequest) - Implements a pipeline architecture (
DocumentOperationPipeline) for consistent request processing - Adds new method overloads accepting request objects to the
Tableclass
Reviewed changes
Copilot reviewed 10 out of 11 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| DocumentOperationRequest.cs | Defines new request object classes for Get, Put, Update, Delete, and Scan operations |
| DocumentOperationPipeline.cs | Implements pipeline infrastructure for validating, mapping, and executing document operations |
| Table.cs | Adds internal helper methods to bridge request objects with the pipeline |
| Table.Sync.cs | Adds synchronous public API methods and interface definitions for request objects |
| Table.Async.cs | Adds asynchronous public API methods for request objects |
| Expression.cs | Adds new methods for applying conditional and update expressions separately |
| TableTests.cs | Comprehensive unit tests for the new request pattern |
| DocumentTests.cs | Integration tests validating end-to-end behavior |
| DataModelTests.cs | Unrelated test for TTL functionality |
| Util.cs | Minor whitespace fix |
| public TResult ExecuteSync(THighLevelRequest request) | ||
| { | ||
| Validate(request); | ||
| var low = Map(request); | ||
| ApplyExpressions(request, low); | ||
| var resp = InvokeSync(low); | ||
| return PostProcess(request, resp); | ||
| } |
Copilot
AI
Nov 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The synchronous execution path is missing a call to Table.UpdateRequestUserAgentDetails(low, isAsync: false) before invoking the service. This call is present in the async path (line 58) and is consistently used throughout the existing codebase for telemetry tracking. Add Table.UpdateRequestUserAgentDetails(low, isAsync: false); after line 42.
sdk/src/Services/DynamoDBv2/Custom/DocumentModel/_bcl/Table.Sync.cs
Outdated
Show resolved
Hide resolved
sdk/src/Services/DynamoDBv2/Custom/DocumentModel/DocumentOperationPipeline.cs
Outdated
Show resolved
Hide resolved
sdk/src/Services/DynamoDBv2/Custom/DocumentModel/DocumentOperationPipeline.cs
Outdated
Show resolved
Hide resolved
| /// <inheritdoc/> | ||
| public async Task<Document> DeleteItemAsync(IDictionary<string, DynamoDBEntry> key, DeleteItemOperationConfig config, CancellationToken cancellationToken = default(CancellationToken)) | ||
| { | ||
| return await DeleteHelperAsync(MakeKey(key), config, cancellationToken).ConfigureAwait(false); | ||
| var operationName = DynamoDBTelemetry.ExtractOperationName(nameof(Table), nameof(DeleteItemAsync)); | ||
| using (DynamoDBTelemetry.CreateSpan(TracerProvider, operationName, spanKind: SpanKind.CLIENT)) | ||
| { | ||
| return await DeleteHelperAsync(MakeKey(key), config, cancellationToken).ConfigureAwait(false); | ||
| } | ||
| } |
Copilot
AI
Nov 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Inconsistent indentation detected. Lines 587-595 have extra indentation compared to the rest of the file. This should align with the same indentation level as other methods in the class.
| [TestMethod] | ||
| [TestCategory("DynamoDBv2")] | ||
| public void TestContext_SaveItem_WithTTL() | ||
| { | ||
| TableCache.Clear(); | ||
| CleanupTables(); | ||
| TableCache.Clear(); | ||
|
|
||
| // Create context and table if needed | ||
| CreateContext(DynamoDBEntryConversion.V2, true); | ||
|
|
||
| // Define TTL to be 2 minutes in the future | ||
| var ttlEpoch = DateTimeOffset.UtcNow.AddMinutes(2).ToUnixTimeSeconds(); | ||
|
|
||
| var item = new TtlTestItem | ||
| { | ||
| Id = 1, | ||
| Data = "Test with TTL", | ||
| Ttl = ttlEpoch | ||
| }; | ||
|
|
||
| Context.Save(item); | ||
|
|
||
| // Load immediately, should exist | ||
| var loaded = Context.Load<TtlTestItem>(item.Id); | ||
| Assert.IsNotNull(loaded); | ||
| Assert.AreEqual(item.Id, loaded.Id); | ||
| Assert.AreEqual(item.Data, loaded.Data); | ||
| Assert.AreEqual(item.Ttl, loaded.Ttl); | ||
|
|
||
| item.Ttl = DateTimeOffset.UtcNow.AddMinutes(3).ToUnixTimeSeconds(); | ||
| Context.Save(item); | ||
| var loaded2 = Context.Load<TtlTestItem>(item.Id); | ||
| Assert.IsNotNull(loaded2); | ||
| Assert.AreEqual(item.Id, loaded2.Id); | ||
| Assert.AreEqual(item.Data, loaded2.Data); | ||
| Assert.AreEqual(item.Ttl, loaded2.Ttl); | ||
| } |
Copilot
AI
Nov 22, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This test appears to be unrelated to the PR's purpose of adding Request Object Pattern for DynamoDB Document Model. The test is about TTL functionality in the DataModel (not DocumentModel) and should likely be in a separate PR. According to the PR description, this PR should only contain changes related to introducing request objects for PutItem, UpdateItem, and DeleteItem operations in the Document Model layer.
Description
New Request Object Types
Introduced three new request classes under
Amazon.DynamoDBv2.DocumentModel:Added new overloads to
Table:Motivation and Context
The existing Amazon.DynamoDBv2.DocumentModel.Table API relies heavily on method overloads for common operations such as PutItem, UpdateItem, and DeleteItem.
This design:
Obscures caller intent and reduces discoverability.
Makes it difficult to extend support for optional features like projections, and expressions.
Uses legacy constructs (Expected, AttributeUpdates, etc.) that are incompatible with expression-based syntax used in modern DynamoDB APIs.
To modernize this surface and align with other AWS SDKs, this PR introduces strongly-typed request objects for PutItem, UpdateItem, and DeleteItem operations in the Document Model layer.
Testing
Screenshots (if appropriate)
Types of changes
Checklist
License