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
Copy file name to clipboardExpand all lines: docs/utilities/idempotency.md
+30-29Lines changed: 30 additions & 29 deletions
Original file line number
Diff line number
Diff line change
@@ -191,11 +191,11 @@ By default, `idempotent_function` serializes, stores, and returns your annotated
191
191
192
192
The output serializer supports any JSON serializable data, **Python Dataclasses** and **Pydantic Models**.
193
193
194
-
!!! info "When using the `output_serializer` parameter, the data will continue to be stored in DynamoDB as a JSON object."
194
+
!!! info "When using the `output_serializer` parameter, the data will continue to be stored in DynamoDB as a JSON string."
195
195
196
196
=== "Pydantic"
197
197
198
-
You can use `PydanticSerializer` to automatically serialize what's retrieved from the persistent storage based on the return type annotated.
198
+
Use `PydanticSerializer` to automatically serialize what's retrieved from the persistent storage based on the return type annotated.
199
199
200
200
=== "Inferring via the return type"
201
201
@@ -215,7 +215,7 @@ The output serializer supports any JSON serializable data, **Python Dataclasses*
215
215
216
216
=== "Dataclasses"
217
217
218
-
You can use `DataclassSerializer` to automatically serialize what's retrieved from the persistent storage based on the return type annotated.
218
+
Use `DataclassSerializer` to automatically serialize what's retrieved from the persistent storage based on the return type annotated.
219
219
220
220
=== "Inferring via the return type"
221
221
@@ -235,7 +235,7 @@ The output serializer supports any JSON serializable data, **Python Dataclasses*
235
235
236
236
=== "Any type"
237
237
238
-
You can use `CustomDictSerializer` to have full control over the serialization process for any type. It expects two functions:
238
+
Use `CustomDictSerializer` to have full control over the serialization process for any type. It expects two functions:
239
239
240
240
* **to_dict**. Function to convert any type to a JSON serializable dictionary before it saves into the persistent storage.
241
241
* **from_dict**. Function to convert from a dictionary retrieved from persistent storage and serialize in its original form.
@@ -248,42 +248,20 @@ The output serializer supports any JSON serializable data, **Python Dataclasses*
248
248
2. This function does the following <br><br>**1**. Receives the dictionary saved into the persistent storage <br>**1** Serializes to `OrderOutput` before `@idempotent` returns back to the caller.
249
249
3. This serializer receives both functions so it knows who to call when to serialize to and from dictionary.
250
250
251
-
#### Batch integration
252
-
253
-
You can can easily integrate with [Batch utility](batch.md){target="_blank"} via context manager. This ensures that you process each record in an idempotent manner, and guard against a [Lambda timeout](#lambda-timeouts) idempotent situation.
254
-
255
-
???+ "Choosing an unique batch record attribute"
256
-
In this example, we choose `messageId` as our idempotency key since we know it'll be unique.
257
-
258
-
Depending on your use case, it might be more accurate [to choose another field](#choosing-a-payload-subset-for-idempotency) your producer intentionally set to define uniqueness.
???+ tip "Tip: Dealing with always changing payloads"
275
254
When dealing with a more elaborate payload, where parts of the payload always change, you should use **`event_key_jmespath`** parameter.
276
255
277
-
Use [`IdempotencyConfig`](#customizing-the-default-behavior) to instruct the idempotent decorator to only use a portion of your payload to verify whether a request is idempotent, and therefore it should not be retried.
256
+
Use [`IdempotencyConfig`](#customizing-the-default-behavior)'s **`event_key_jmespath`** parameter to select one or more payload parts as your idempotency key.
278
257
279
258
> **Payment scenario**
280
259
281
260
In this example, we have a Lambda handler that creates a payment for a user subscribing to a product. We want to ensure that we don't accidentally charge our customer by subscribing them more than once.
282
261
283
-
Imagine the function executes successfully, but the client never receives the response due to a connection issue. It is safe to retry in this instance, as the idempotent decorator will return a previously saved response.
262
+
Imagine the function runs successfully, but the client never receives the response due to a connection issue. It is safe to immediately retry in this instance, as the idempotent decorator will return a previously saved response.
284
263
285
-
**What we want here** is to instruct Idempotency to use `user_id` and `product_id` fields from our incoming payload as our idempotency key.
286
-
If we were to treat the entire request as our idempotency key, a simple HTTP header change would cause our customer to be charged twice.
264
+
**We want** to use `user_id` and `product_id` fields as our idempotency key. If we were to treat the entire request as our idempotency key, a simple HTTP header change would cause our function to run again.
287
265
288
266
???+ tip "Deserializing JSON strings in payloads for increased accuracy."
289
267
The payload extracted by the `event_key_jmespath` is treated as a string by default.
@@ -472,6 +450,29 @@ You can customize attribute names when instantiating `RedisCachePersistenceLayer
You can can easily integrate with [Batch](batch.md){target="_blank"} with the [idempotent_function decorator](#idempotent_function-decorator) to handle idempotency per message/record in a given batch.
458
+
459
+
???+ "Choosing an unique batch record attribute"
460
+
In this example, we choose `messageId` as our idempotency key since we know it'll be unique.
461
+
462
+
Depending on your use case, it might be more accurate [to choose another field](#choosing-a-payload-subset-for-idempotency) your producer intentionally set to define uniqueness.
0 commit comments