Skip to content
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

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

Merged
merged 12 commits into from
Aug 13, 2024
1 change: 0 additions & 1 deletion .markdownlintignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ LICENSE
# these will be removed from the ignore and linted in future PRs
packages/batch/README.md
packages/commons/README.md
packages/idempotency/README.md
packages/jmespath/README.md
packages/logger/README.md
packages/metrics/README.md
Expand Down
26 changes: 24 additions & 2 deletions docs/utilities/idempotency.md
am29d marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ title: Idempotency
description: Utility
---

<!-- markdownlint-disable MD043 -->

The idempotency utility provides a simple solution to convert your Lambda functions into idempotent operations which are safe to retry.

## Key features
Expand Down Expand Up @@ -744,6 +742,30 @@ Below an example implementation of a custom persistence layer backed by a generi

For example, the `_putRecord()` method needs to throw an error if a non-expired record already exists in the data store with a matching key.

## Testing your code
dreamorosi marked this conversation as resolved.
Show resolved Hide resolved

The idempotency utility provides several routes to test your code.

### Disabling the idempotency utility

When testing your code, you may wish to disable the idempotency logic altogether and focus on testing your business logic. To do this, you can set the environment variable POWERTOOLS_IDEMPOTENCY_DISABLED with a truthy value.

### Testing with local DynamoDB

When testing your Lambda function locally, you can use a local DynamoDB instance to test the idempotency feature. You can use [DynamoDB Local](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.DownloadingAndRunning.html) or [LocalStack](https://localstack.cloud/){target="_blank"}.

=== "handler.test.ts"

```typescript hl_lines="7-9"
--8<-- "examples/snippets/idempotency/workingWithLocalDynamoDB.test.ts"
```

=== "handler.ts"

```typescript hl_lines="7-9"
--8<-- "examples/snippets/idempotency/workingWithLocalDynamoDB.ts"
```

## Extra resources

If you're interested in a deep dive on how Amazon uses idempotency when building our APIs, check out
Expand Down
40 changes: 40 additions & 0 deletions examples/snippets/idempotency/workingWithLocalDynamoDB.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { makeIdempotent } from '@aws-lambda-powertools/idempotency';
import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb';
import type { Context } from 'aws-lambda';
import { handler } from './workingWithLocalDynamoDB';

describe('Idempotent handler', () => {
const lambdaContext = {
functionName: 'foo-bar-function',
memoryLimitInMB: '128',
invokedFunctionArn:
'arn:aws:lambda:eu-west-1:123456789012:function:foo-bar-function',
awsRequestId: 'c6af9ac6-7b61-11e6-9a41-93e812345678',
getRemainingTimeInMillis: () => 1234,
} as Context;

const mockPersistenceStore = new DynamoDBPersistenceLayer({
tableName: 'IdempotencyTable',
clientConfig: { endpoint: 'http://localhost:8000' }, // 8000 for local DynamoDB and 4566 for LocalStack
});

const idempotentHandler = makeIdempotent(handler, {
persistenceStore: mockPersistenceStore,
});

it('should return the same response', async () => {
const response = await idempotentHandler(
{
foo: 'bar',
},
lambdaContext
);
expect(response).toEqual({
statusCode: 200,
body: JSON.stringify({
paymentId: '123',
message: 'Payment created',
}),
});
});
});
23 changes: 23 additions & 0 deletions examples/snippets/idempotency/workingWithLocalDynamoDB.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { makeIdempotent } from '@aws-lambda-powertools/idempotency';
import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb';
import type { Context } from 'aws-lambda';

const ddbPersistenceStore = new DynamoDBPersistenceLayer({
tableName: 'IdempotencyTable',
});

const handler = async (event: unknown, context: Context) => {
return {
statusCode: 200,
body: JSON.stringify({
paymentId: '123',
message: 'Payment created',
}),
};
};

const idempotentHandler = makeIdempotent(handler, {
persistenceStore: ddbPersistenceStore,
});

export { idempotentHandler, handler };
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"docs-generateApiDoc": "typedoc .",
"docs-runLocalApiDoc": "npx live-server api",
"postpublish": "git restore .",
"lint:markdown": "markdownlint-cli2 '**/*.md' '#node_modules' '#**/*/node_modules' '#docs/changelog.md' '#LICENSE.md' '#.github' '#**/*/CHANGELOG.md' '#examples/app/README.md' '#packages/commons/README.md' '#packages/idempotency/README.md' '#packages/jmespath/README.md' '#packages/logger/README.md' '#packages/metrics/README.md' '#packages/parameters/README.md' '#packages/parser/README.md' '#packages/tracer/README.md'"
"lint:markdown": "markdownlint-cli2 '**/*.md' '#node_modules' '#**/*/node_modules' '#docs/changelog.md' '#LICENSE.md' '#.github' '#**/*/CHANGELOG.md' '#examples/app/README.md' '#packages/commons/README.md' '#packages/jmespath/README.md' '#packages/logger/README.md' '#packages/metrics/README.md' '#packages/parameters/README.md' '#packages/parser/README.md' '#packages/tracer/README.md'"
},
"repository": {
"type": "git",
Expand Down
Loading