Description
Use case
I wan to have an option to call a function when idempotency is triggered. In some cases I want to either change payload to signal to the caller that this request was idempotent (x-idempotency: true
) or to have side effects, i.e. add custom metric.
While we have this option in python with idempotency_hook
there is no option available int TypeScript.
Solution/User Experience
import type { IdempotencyRecord } from '@aws-lambda-powertools/idempotency/persistence';
import {
IdempotencyConfig,
makeIdempotent,
} from '@aws-lambda-powertools/idempotency';
import type { Context } from 'aws-lambda';
import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb';
interface HandlerReponse {
message: string;
statusCode: number;
headers?: Record<string, string>;
}
const myCustomHook = async (
response: HandlerReponse,
record: IdempotencyRecord
) => {
response.headers['x-idempotency-key'] = record.idempotencyKey;
return response;
};
const config = new IdempotencyConfig({
reponseHook: myCustomHook,
});
const hanlder = async (event: unknown, context: Context) => {
// ... process your event
return {
message: 'success',
statusCode: 200,
};
};
const persistenceStore = new DynamoDBPersistenceLayer({
tableName: 'idempotencyTableName',
});
const idempotentHandler = makeIdempotent(hanlder, {
config: config,
persistenceStore: persistenceStore,
});
Following the Python implementation, we would add resposneHook
option to the config, that takes a function as a parameters. The response hook function has signature with response
and idempotencyRecord
and returns a modified version of the response. The response
type should match the return type of the handler function.
Alternative solutions
No response
Acknowledgment
- This feature request meets Powertools for AWS Lambda (TypeScript) Tenets
Future readers
Please react with 👍 and your use case to help us understand customer demand.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Activity
dreamorosi commentedon Aug 6, 2024
Good point - we are missing this feature and it'd be good to have it for feature parity.
I'm going to mark it as contributions welcome.
Note
For those interested in contributing, please leave a comment below so that we can assign the issue to you and make sure we don't duplicate efforts. Also, if you have any further questions please don't hesitate to ask here or on our Discord channel.
arnabrahman commentedon Sep 4, 2024
I would like to contribute to this but I need some pointers.
I believe if the custom hook function is provided, it should be called from here. Something like this?
Once again, I need your expert opinion on this, @dreamorosi. Thanks.
dreamorosi commentedon Sep 10, 2024
Hi @arnabrahman, thanks for giving some traction to this feature.
I've looked at the implementation in Powertools for AWS Lambda (Python) and it roughly matches the suggestion you shared above. In their implementation they call the hook in the equivalent of our
IdempotencyHandler.determineResultFromIdempotencyRecord
method just before returning, which is pretty much the same as you are suggesting1.Normally I would advocate for consistency across projects for this type of feature, mainly to reduce the cognitive load for recurrent maintainers by having similar implementation.
In this case we might not be able to the same unless we change the
determineResultFromIdempotencyRecord()
method fromstatic
to normal, so that it can access the config object. Assuming we make the method non-static, I would be inclined to add the logic within thedetermineResultFromIdempotencyRecord()
method instead.Regarding the actual implementation, I think the logic you're suggesting makes sense, so from my side we're good to move forward if you're still interested.
Footnotes
In their implementation they also do the equivalent of an
undefined
check - which is a bug that I have reported (Bug: response hook is not called when idempotent function returnsNone
powertools-lambda-python#5150). ↩arnabrahman commentedon Sep 11, 2024
Yes, I am interested. Please assign me on this, @dreamorosi
15 remaining items