Skip to content

Idempotent documentation examples could be misleading #657

Closed
@walmsles

Description

@walmsles

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)

Metadata

Metadata

Assignees

Labels

documentationImprovements or additions to documentationp1

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions