-
Notifications
You must be signed in to change notification settings - Fork 153
Feature request: Be able to have more flexibility with how the idempotency key is being handled #3540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Thanks for opening your first issue here! We'll come back to you as soon as we can. |
Hi @wizardone, thank you for opening this feature request and for taking the time to propose alternatives. Before moving forward with the discussion, I'd like to understand your use case a bit better. I am not asking you to disclose anything specific to your workload, but rather understand the root cause of wanting to have full control over the idempotency key. My question comes from two angles: 1/ understanding whether what you want to achieve can be done in other ways with the current API, or 2/ if not, understanding whether the use case/need is broad and generic enough that it might be useful for other customers - this last, in turn, will play a significant part in our decision of implementing this or not. Thank you in advance, also in the meanwhile, would you mind taking a look at this other feature request (#3515) that is already being implemented, to see if it might cover part of all your needs? |
Hey @wizardone thanks a lot for opening this and bringing up some ideas for your specific use case! In addition of what @dreamorosi already told, I have some special concerns here about the Idempotency mechanism.
If I'm understanding correctly, and please correct if I'm wrong, you want to have an experience like this: const createSubscriptionPayment = makeIdempotent(
async (
transactionId: string,
event: Request
): Promise<SubscriptionResult> => {
// ... create payment
return {
id: transactionId,
productId: event.productId,
};
},
{
persistenceStore,
dataIndexArgument: 1,
config,
myIdempotencyKeyWithHash: "myKeyWithHash"
}
); In this case, if you use the The AWS Well-Architected Framework defines idempotency in the chapter REL04-BP04 Make mutating operations idempotent as follows:
So, in this case you can create an artificial key and no matter the payload you will always have the same key, since we will no longer calculate the IdempotencyKey based on the payload, making this function response cached and no matter the payload. I'm not sure we should go down that route and make this available to customers. We need to have some guardrails in place.
Can you explain a bit more why you need to control the digest mechanism? We create a digest, which is a small value/signature of the entire message, and in our case it is a one-way process, making it irreversible. After creating the digest, we just use it to query DynamoDB in subsequent invocations, we don't roll it back to original value. Again, please let me know if I am wrong in my understanding and I'm more than happy to discuss this solution. |
Thank you both for your responses. Powertools is great and it mostly gets me covered: I can specify the dynamo table, primary key, etc, but in the end if the digest is different I'm lost :) |
Hello @wizardone! Thanks for telling us about your use case. What you shared is more than enough and for me this is a very interesting use case for Idempotency. I must be honest, I never thought about integrating two Idempotency implementations and make it work, nice! While we can’t add this feature to our codebase for some of the concerns we’ve raised before, we're working on a new feature that gives you more control over your idempotency keys prefix. Instead of always using Keep in mind that import { DynamoDBPersistenceLayer, idempotent } from '@aws-lambda-powertools/idempotency';
import { Context } from 'aws-lambda';
class MyOwnPersistenceLayer extends DynamoDBPersistenceLayer {
protected getHashedIdempotencyKey(data: JSONValue): string | null {
return this.idempotencyKeyPrefix; // When working with keyPrefix, this will return always what you set as keyPrefix and will ignore the payload calculation.
}
const persistenceLayer = new MyOwnPersistenceLayer({ tableName: "ddbidempotency" });
const lambdaHandler = idempotent(
async (event: Record<string, any>, context: Context) => {
return "ABBB";
},
{
persistenceStore: persistenceLayer,
keyPrefix: "aaaa"
}
);
export { lambdaHandler }; My TypeScript skills isn't the best and you'll probably need to make some small changes to this example, but consider this as a baseline to get some insights on solving your challenge. Please let us know if we can help with anything else. |
Just to clarify, the above method won't work unless we change the access modifier here from Once done, you'll be able to completely modify the implementation of the method and return any string value you want: import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb';
import type { JSONValue } from '@aws-lambda-powertools/commons/types';
class MyOwnPersistenceLayer extends DynamoDBPersistenceLayer {
getHashedIdempotencyKey(data: JSONValue): string {
return 'foo'; // this string will be used as idempotency key - use with caution
}
}
// use MyOwnPersistenceLayer as you would DynamoDBPersistenceLayer I'll open a PR shortly and the change will land in the next release. |
This issue is now closed. Please be mindful that future comments are hard for our team to see. If you need more assistance, please either tag a team member or open a new issue that references this one. If you wish to keep having a conversation with other community members under this issue feel free to do so. |
Thank you very much for your time, appreciate it! |
This is now released under v2.14.0 version! |
Use case
Hello folks, while migrating a lambda function to use powertools I really needed to have slightly more control over the idempotency key and after reading the docs and code extensively I don't think there is currently support for what I'm after. In a nutshell:
hex
if I wanted to.Both options are interconnected for my particular use case. In other words if I'm able to specify the digest, then powertools will give me everything I need. Otherwise I would like to have the freedom to generate what I need myself and use it.
I appreciate if that level of control is not something that you'd like to provide, my use cases are very specific and powertools already gives flexibility. Still, let me know if either option makes sense to you. Thank you.
Solution/User Experience
Implementing giving the option to set digest can be as low touch as adding a new configuration option to the IdempotencyConfig:
pseudo code:
Implementing the option to hash or not might be slightly more involving and I'm not aware of the nuances of the code, but a very rough implementation could be:
Alternative solutions
Acknowledgment
Future readers
Please react with 👍 and your use case to help us understand customer demand.
The text was updated successfully, but these errors were encountered: