You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
* Add responseHook definition to IdempotencyConfig and call from IdempotencyHandler. Update idempotency example with an example use-case modifying API GW headers.
* Make debug log message more concise in IdempotencyHandler.java.
* Add unit test for idempotency response hook.
* Document idempotency response hook feature.
* Update examples/powertools-examples-idempotency/src/main/java/helloworld/App.java
Co-authored-by: Leandro Damascena <[email protected]>
---------
Co-authored-by: Leandro Damascena <[email protected]>
| **EventKeyJMESPath** | `""` | JMESPath expression to extract the idempotency key from the event record. See available [built-in functions](serialization) |
595
+
| **EventKeyJMESPath** | `""` | JMESPath expression to extract the idempotency key from the event record. See available [built-in functions](serialization) |
595
596
| **PayloadValidationJMESPath** | `""` | JMESPath expression to validate whether certain parameters have changed in the event |
596
-
| **ThrowOnNoIdempotencyKey** | `False` | Throw exception if no idempotency key was found in the request |
597
+
| **ThrowOnNoIdempotencyKey** | `false` | Throw exception if no idempotency key was found in the request |
597
598
| **ExpirationInSeconds** | 3600 | The number of seconds to wait before a record is expired |
| **LocalCacheMaxItems** | 256 | Max number of items to store in local cache |
600
601
| **HashFunction** | `MD5` | Algorithm to use for calculating hashes, as supported by `java.security.MessageDigest` (eg. SHA-1, SHA-256, ...) |
602
+
| **ResponseHook** | `null` | Response hook to apply modifications to idempotent responses |
601
603
602
604
These features are detailed below.
603
605
@@ -855,6 +857,58 @@ You can extend the `BasePersistenceStore` class and implement the abstract metho
855
857
856
858
For example, the `putRecord` method needs to throw an exception if a non-expired record already exists in the data store with a matching key.
857
859
860
+
### Manipulating the Idempotent Response
861
+
862
+
You can set up a response hook in the Idempotency configuration to manipulate the returned data when an operation is idempotent. The hook function will be called with the current de-serialized response `Object` and the Idempotency `DataRecord`.
863
+
864
+
The example below shows how to append an HTTP header to an `APIGatewayProxyResponseEvent`.
865
+
866
+
=== "Using an Idempotent Response Hook"
867
+
868
+
```java hl_lines="3-20"
869
+
Idempotency.config().withConfig(
870
+
IdempotencyConfig.builder()
871
+
.withResponseHook((responseData, dataRecord) -> {
872
+
if (responseData instanceof APIGatewayProxyResponseEvent) {
873
+
APIGatewayProxyResponseEvent proxyResponse =
874
+
(APIGatewayProxyResponseEvent) responseData;
875
+
final Map<String, String> headers = new HashMap<>();
The response hook is called after de-serialization so the payload you process will be the de-serialized Java object.
900
+
901
+
#### Being a good citizen
902
+
903
+
When using response hooks to manipulate returned data from idempotent operations, it's important to follow best practices to avoid introducing complexity or issues. Keep these guidelines in mind:
904
+
905
+
1. **Response hook works exclusively when operations are idempotent.** The hook will not be called when an operation is not idempotent, or when the idempotent logic fails.
906
+
907
+
2. **Catch and Handle Exceptions.** Your response hook code should catch and handle any exceptions that may arise from your logic. Unhandled exceptions will cause the Lambda function to fail unexpectedly.
908
+
909
+
3. **Keep Hook Logic Simple** Response hooks should consist of minimal and straightforward logic for manipulating response data. Avoid complex conditional branching and aim for hooks that are easy to reason about.
* This is our Lambda event handler. It accepts HTTP POST requests from API gateway and returns the contents of the given URL. Requests are made idempotent
76
+
* This is your Lambda event handler. It accepts HTTP POST requests from API gateway and returns the contents of the
77
+
* given URL. Requests are made idempotent
62
78
* by the idempotency library, and results are cached for the default 1h expiry time.
63
79
* <p>
64
80
* You can test the endpoint like this:
@@ -67,8 +83,10 @@ public App(DynamoDbClient client) {
* <li>First call will execute the handleRequest normally, and store the response in the idempotency table (Look into DynamoDB)</li>
71
-
* <li>Second call (and next ones) will retrieve from the cache (if cache is enabled, which is by default) or from the store, the handler won't be called. Until the expiration happens (by default 1 hour).</li>
86
+
* <li>First call will execute the handleRequest normally, and store the response in the idempotency table (Look
87
+
* into DynamoDB)</li>
88
+
* <li>Second call (and next ones) will retrieve from the cache (if cache is enabled, which is by default) or from
89
+
* the store, the handler won't be called. Until the expiration happens (by default 1 hour).</li>
72
90
* </ul>
73
91
*/
74
92
@Idempotent// The magic is here!
@@ -101,14 +119,14 @@ public APIGatewayProxyResponseEvent handleRequest(final APIGatewayProxyRequestEv
101
119
}
102
120
}
103
121
104
-
105
122
/**
106
123
* Helper to retrieve the contents of the given URL and return them as a string.
107
124
* <p>
108
125
* We could also put the @Idempotent annotation here if we only wanted this sub-operation to be idempotent. Putting
109
126
* it on the handler, however, reduces total execution time and saves us time!
Copy file name to clipboardExpand all lines: powertools-idempotency/powertools-idempotency-core/src/main/java/software/amazon/lambda/powertools/idempotency/IdempotencyConfig.java
0 commit comments