Skip to content

docs(idempotency): review API docs & README #2917

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

Merged
merged 12 commits into from
Aug 13, 2024
18 changes: 5 additions & 13 deletions packages/idempotency/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ Powertools for AWS Lambda (TypeScript) is a developer toolkit to implement Serve
You can use the package in both TypeScript and JavaScript code bases.

- [Intro](#intro)
- [Key features](#key-features)
- [Usage](#usage)
- [Function wrapper](#function-wrapper)
- [Decorator](#decorator)
Expand All @@ -27,14 +26,6 @@ You can either use it to wrap a function, decorate a method, or as Middy middlew

The current implementation provides a persistence layer for Amazon DynamoDB, which offers a variety of configuration options. You can also bring your own persistence layer by extending the `BasePersistenceLayer` class.

## Key features

- Prevent Lambda handler from executing more than once on the same event payload during a time window
- Ensure Lambda handler returns the same result when called with the same payload
- Select a subset of the event as the idempotency key using JMESPath expressions
- Set a time window in which records with the same payload should be considered duplicates
- Expires in-progress executions if the Lambda function times out halfway through

## Usage

To get started, install the library by running:
Expand All @@ -49,15 +40,15 @@ Next, review the IAM permissions attached to your AWS Lambda function and make s

You can make any function idempotent, and safe to retry, by wrapping it using the `makeIdempotent` higher-order function.

The function wrapper takes a reference to the function to be made idempotent as first argument, and an object with options as second argument.
The `makeIdempotent` function takes a reference to the function to be made idempotent as first argument, and an object with options as second argument.

When you wrap your Lambda handler function, the utility uses the content of the `event` parameter to handle the idempotency logic.

```ts
import { makeIdempotent } from '@aws-lambda-powertools/idempotency';
import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb';
import type { Context, APIGatewayProxyEvent } from 'aws-lambda';

``
const persistenceStore = new DynamoDBPersistenceLayer({
tableName: 'idempotencyTableName',
});
Expand Down Expand Up @@ -255,7 +246,8 @@ The decorator configuration options are identical with the ones of the `makeIdem

If instead you use Middy, you can use the `makeHandlerIdempotent` middleware. When using the middleware your Lambda handler becomes idempotent.

By default, the Idempotency utility will use the full event payload to create an hash and determine if a request is idempotent, and therefore it should not be retried. When dealing with a more elaborate payload, where parts of the payload always change you should use the `IdempotencyConfig` object to instruct the utility to only use a portion of your payload. This is useful when dealing with payloads that contain timestamps or request ids.
By default, the Idempotency utility will use the full event payload to create an hash and determine if a request is idempotent, and therefore it should not be retried.
When dealing with a more elaborate payload, where parts of the payload always change you should use the `IdempotencyConfig` object to instruct the utility to only use a portion of your payload. This is useful when dealing with payloads that contain timestamps or request ids.

```ts
import { IdempotencyConfig } from '@aws-lambda-powertools/idempotency';
Expand Down Expand Up @@ -314,7 +306,7 @@ Help us prioritize upcoming functionalities or utilities by [upvoting existing R

### Becoming a reference customer

Knowing which companies are using this library is important to help prioritize the project internally. If your company is using Powertools for AWS Lambda (TypeScript), you can request to have your name and logo added to the README file by raising a [Support Powertools for AWS Lambda (TypeScript) (become a reference)](https://github.com/aws-powertools/powertools-lambda-typescript/issues/new?assignees=&labels=customer-reference&template=support_powertools.yml&title=%5BSupport+Lambda+Powertools%5D%3A+%3Cyour+organization+name%3E) issue.
Knowing which companies are using this library is important to help prioritize the project internally. If your company is using Powertools for AWS Lambda (TypeScript), you can request to have your name and logo added to the README file by raising a [Support Powertools for AWS Lambda (TypeScript) (become a reference)](https://s12d.com/become-reference-pt-ts) issue.

The following companies, among others, use Powertools:

Expand Down
8 changes: 4 additions & 4 deletions packages/idempotency/src/IdempotencyConfig.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { EnvironmentVariablesService } from './config/EnvironmentVariablesService.js';
import { PowertoolsFunctions } from '@aws-lambda-powertools/jmespath/functions';
import type { JMESPathParsingOptions } from '@aws-lambda-powertools/jmespath/types';
import type { Context } from 'aws-lambda';
import { EnvironmentVariablesService } from './config/EnvironmentVariablesService.js';
import type { IdempotencyConfigOptions } from './types/IdempotencyOptions.js';
import type { JMESPathParsingOptions } from '@aws-lambda-powertools/jmespath/types';
import { PowertoolsFunctions } from '@aws-lambda-powertools/jmespath/functions';

/**
* Configuration for the idempotency feature.
Expand Down Expand Up @@ -52,9 +52,9 @@ class IdempotencyConfig {
* @default false
*/
public throwOnNoIdempotencyKey: boolean;

/**
* Use the local cache to store idempotency keys.
* @see {@link LRUCache}
*/
public useLocalCache: boolean;
readonly #envVarsService: EnvironmentVariablesService;
Expand Down
6 changes: 3 additions & 3 deletions packages/idempotency/src/IdempotencyHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ export class IdempotencyHandler<Func extends AnyFunction> {
await this.#deleteInProgressRecord();
throw error;
}
await this.#saveSuccessfullResult(result);
await this.#saveSuccessfulResult(result);

return result;
}
Expand Down Expand Up @@ -208,7 +208,7 @@ export class IdempotencyHandler<Func extends AnyFunction> {
* @param response The response returned by the handler.
*/
public async handleMiddyAfter(response: unknown): Promise<void> {
await this.#saveSuccessfullResult(response as ReturnType<Func>);
await this.#saveSuccessfulResult(response as ReturnType<Func>);
}

/**
Expand Down Expand Up @@ -401,7 +401,7 @@ export class IdempotencyHandler<Func extends AnyFunction> {
*
* @param result The result returned by the handler.
*/
#saveSuccessfullResult = async (result: ReturnType<Func>): Promise<void> => {
#saveSuccessfulResult = async (result: ReturnType<Func>): Promise<void> => {
try {
await this.#persistenceStore.saveSuccess(
this.#functionPayloadToBeHashed,
Expand Down
4 changes: 3 additions & 1 deletion packages/idempotency/src/idempotencyDecorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,9 @@ import type {
* }
* }
* ```
* @see {@link DynamoDBPersistenceLayer}
*
* @param options - Options to configure the idempotency behavior
* @see {@link persistence/DynamoDBPersistenceLayer.DynamoDBPersistenceLayer | DynamoDBPersistenceLayer}
* @see https://www.typescriptlang.org/docs/handbook/decorators.html
*/
const idempotent = function (
Expand Down
2 changes: 2 additions & 0 deletions packages/idempotency/src/makeIdempotent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ const isOptionsWithDataIndexArgument = (
* return Promise.resolve();
* };
*
* @param fn - the function to make idempotent
* @param options - the options to configure the idempotency behavior
* ```
*/
function makeIdempotent<Func extends AnyFunction>(
Expand Down
4 changes: 2 additions & 2 deletions packages/idempotency/src/types/IdempotencyOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { BasePersistenceLayer } from '../persistence/BasePersistenceLayer.j
* Configuration options for the idempotency utility.
*
* When making a function idempotent you should always set
* a persistence store (i.e. {@link DynamoDBPersistenceLayer}).
* a persistence store (i.e. @see {@link persistence/DynamoDBPersistenceLayer.DynamoDBPersistenceLayer | DynamoDBPersistenceLayer}).
*
* Optionally, you can also pass a custom configuration object,
* this allows you to customize the behavior of the idempotency utility.
Expand Down Expand Up @@ -111,7 +111,7 @@ type ItempotentFunctionOptions<T extends Array<any>> = T[1] extends Context
* Options to configure the behavior of the idempotency logic.
*
* This is an internal type that is used by the Idempotency utility to
* configure {@link IdempotencyHandler}.
* configure.
*/
type IdempotencyHandlerOptions = {
/**
Expand Down
6 changes: 6 additions & 0 deletions packages/idempotency/src/types/IdempotencyRecord.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import type { JSONValue } from '@aws-lambda-powertools/commons/types';
import type { IdempotencyRecordStatus } from '../constants.js';

/**
* The status of an IdempotencyRecord
*/
type IdempotencyRecordStatusValue =
(typeof IdempotencyRecordStatus)[keyof typeof IdempotencyRecordStatus];

/**
* Options for creating a new IdempotencyRecord
*/
type IdempotencyRecordOptions = {
idempotencyKey: string;
status: IdempotencyRecordStatusValue;
Expand Down
1 change: 1 addition & 0 deletions packages/idempotency/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ export type {
IdempotencyConfigOptions,
IdempotencyLambdaHandlerOptions,
IdempotencyHandlerOptions,
ItempotentFunctionOptions,
} from './IdempotencyOptions.js';
2 changes: 1 addition & 1 deletion packages/idempotency/typedoc.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
"./src/types/index.ts",
"./src/middleware/index.ts",
"./src/persistence/index.ts",
"./src/persistence/DynamoDBPersistenceLayer.ts",
"./src/persistence/DynamoDBPersistenceLayer.ts"
],
"readme": "README.md"
}