Description
What were you initially searching for in the docs?
How to use the Idempotent utility
Is this related to an existing part of the documentation? Please share a link
Link to documentation section
Describe how we could make it clearer
The example uses the following config:
config = IdempotencyConfig(event_key_jmespath="body")
What I feel is missing from the documentation is that the Idempotent decorator does not do any type coersion on the event_key_jmespath so this data hash key used in dynamodb is based on the String data in the event body attribute.
For a standard APIGatewayProxyEvent for a json REST Api that means the following body strings are different even though logically the API Json payloads are actually identical (in API terms). If I follow the example verbatim the following body values will be seen as different API invocations:
{
"more_data": "more data 1",
"data": "test message 1"
}
{
"more_data": "more data 1",
"data": "test message 1"
}
{
"more_data": "more data 1",
"data": "test message 1"
}
maps to a body of "{\n\n "more_data": "more data 1",\n\n\n\n\n\n\n\n"data": "test message 1"\n\n}" in the API Gateway event (i.e. includes all the white space).
I feel the example should include the event source for API Gateway events resulting in the following:
import json
from aws_lambda_powertools.utilities.idempotency import (
IdempotencyConfig, DynamoDBPersistenceLayer, idempotent
)
from aws_lambda_powertools.utilities.data_classes import (
event_source, APIGatewayProxyEvent
)
persistence_layer = DynamoDBPersistenceLayer(table_name="IdempotencyTable")
config = IdempotencyConfig(event_key_jmespath="json_body")
@event_source(data_class=APIGatewayProxyEvent)
@idempotent(config=config, persistence_store=persistence_layer)
def handler(event:APIGatewayProxyEvent, context):
body = json.loads(event['body'])
payment = create_subscription_payment(
user=body['user'],
product=body['product_id']
)
...
return {
"payment_id": payment.id,
"message": "success",
"statusCode": 200
}
If you have a proposed update, please share it here
Maybe change the example to include the event_source coersion to stop people copying that example thinking their API will be idempotent - when it will when the exact body string is used. Its not obvious from the documentation (or maybe its just me)