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
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -188,11 +188,11 @@ By default, `idempotent_function` serializes, stores, and returns your annotated
188
188
189
189
The output serializer supports any JSON serializable data, **Python Dataclasses** and **Pydantic Models**.
190
190
191
-
!!! info "When using the `output_serializer` parameter, the data will continue to be stored in DynamoDB as a JSON object."
191
+
!!! info "When using the `output_serializer` parameter, the data will continue to be stored in DynamoDB as a JSON string."
192
192
193
193
=== "Pydantic"
194
194
195
-
You can use `PydanticSerializer` to automatically serialize what's retrieved from the persistent storage based on the return type annotated.
195
+
Use `PydanticSerializer` to automatically serialize what's retrieved from the persistent storage based on the return type annotated.
196
196
197
197
=== "Inferring via the return type"
198
198
@@ -212,7 +212,7 @@ The output serializer supports any JSON serializable data, **Python Dataclasses*
212
212
213
213
=== "Dataclasses"
214
214
215
-
You can use `DataclassSerializer` to automatically serialize what's retrieved from the persistent storage based on the return type annotated.
215
+
Use `DataclassSerializer` to automatically serialize what's retrieved from the persistent storage based on the return type annotated.
216
216
217
217
=== "Inferring via the return type"
218
218
@@ -232,7 +232,7 @@ The output serializer supports any JSON serializable data, **Python Dataclasses*
232
232
233
233
=== "Any type"
234
234
235
-
You can use `CustomDictSerializer` to have full control over the serialization process for any type. It expects two functions:
235
+
Use `CustomDictSerializer` to have full control over the serialization process for any type. It expects two functions:
236
236
237
237
* **to_dict**. Function to convert any type to a JSON serializable dictionary before it saves into the persistent storage.
238
238
* **from_dict**. Function to convert from a dictionary retrieved from persistent storage and serialize in its original form.
@@ -245,42 +245,20 @@ The output serializer supports any JSON serializable data, **Python Dataclasses*
245
245
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.
246
246
3. This serializer receives both functions so it knows who to call when to serialize to and from dictionary.
247
247
248
-
#### Batch integration
249
-
250
-
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.
251
-
252
-
???+ "Choosing an unique batch record attribute"
253
-
In this example, we choose `messageId` as our idempotency key since we know it'll be unique.
254
-
255
-
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"
272
251
When dealing with a more elaborate payload, where parts of the payload always change, you should use **`event_key_jmespath`** parameter.
273
252
274
-
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.
253
+
Use [`IdempotencyConfig`](#customizing-the-default-behavior)'s **`event_key_jmespath`** parameter to select one or more payload parts as your idempotency key.
275
254
276
255
> **Payment scenario**
277
256
278
257
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.
279
258
280
-
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.
259
+
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.
281
260
282
-
**What we want here** is to instruct Idempotency to use `user_id` and `product_id` fields from our incoming payload as our idempotency key.
283
-
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.
261
+
**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.
284
262
285
263
???+ tip "Deserializing JSON strings in payloads for increased accuracy."
286
264
The payload extracted by the `event_key_jmespath` is treated as a string by default.
@@ -469,6 +447,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.
455
+
456
+
???+ "Choosing an unique batch record attribute"
457
+
In this example, we choose `messageId` as our idempotency key since we know it'll be unique.
458
+
459
+
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