Skip to content

Commit 9d8df3d

Browse files
erikayao93dreamorosiAlexander Schuerendependabot[bot]github-actions[bot]
authored
feat(batch): Implementation of base batch processing classes (#1588)
* chore: init workspace * chore: init workspace * Initial base class implementation * Added BatchProcessor implementation, attempted fix for async * Added unit tests * Refactoring unit tests * Lint fix, updated docstrings * Added response and identifier typings * test(idempotency): improve integration tests for utility (#1591) * docs: new name * chore: rename e2e files * tests(idempotency): expand integration tests * chore(idempotency): remove unreachable code * Removed unnecessary type casting * Moved exports for handlers and factories * Updated imports, refactored randomization in factories * Refactored EventType to be const instead of enum * Refactored and added documentation for errors * Removed debugging line * chore(ci): add canary to layer deployment (#1593) * docs(idempotency): write utility docs (#1592) * docs: base docs * wip * chore: added paths to snippets tsconfig * chore: added page to docs menu * docs(idempotency): utility docs * highlights * chore: remove CDK mention * build(internal): bump semver from 5.7.1 to 5.7.2 (#1594) Bumps [semver](https://github.com/npm/node-semver) from 5.7.1 to 5.7.2. - [Release notes](https://github.com/npm/node-semver/releases) - [Changelog](https://github.com/npm/node-semver/blob/v5.7.2/CHANGELOG.md) - [Commits](npm/node-semver@v5.7.1...v5.7.2) --- updated-dependencies: - dependency-name: semver dependency-type: indirect ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(idempotency): mark the utility ready public beta (#1595) * chore(idempotency): mark utility as public beta * chore: manually increment version in commons * docs(internal): update AWS SDK links to new docs (#1597) * chore(maintenance): remove parameters utility from layer bundling and layers e2e tests (#1599) * remove parameter from e2e tests * remove parameters from canary stack as well * chore(release): v1.11.1 [skip ci] * fix canary deploy in ci with correct workspace name (#1601) * chore: update layer ARN on documentation --------- Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: Andrea Amorosi <[email protected]> Co-authored-by: Alexander Schueren <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Release bot[bot] <[email protected]>
1 parent 7f27b7c commit 9d8df3d

File tree

73 files changed

+3835
-505
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+3835
-505
lines changed

Diff for: .github/scripts/release_patch_package_json.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ if (process.argv.length < 3) {
1717
}
1818
const basePath = resolve(process.argv[2]);
1919
const packageJsonPath = join(basePath, 'package.json');
20-
const alphaPackages = ['@aws-lambda-powertools/idempotency'];
21-
const betaPackages = [];
20+
const alphaPackages = [];
21+
const betaPackages = ['@aws-lambda-powertools/idempotency'];
2222

2323
(() => {
2424
try {

Diff for: .github/workflows/reusable_deploy_layer_stack.yml

+2
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ jobs:
9494
path: ./cdk-layer-stack/* # NOTE: upload-artifact does not inherit working-directory setting.
9595
if-no-files-found: error
9696
retention-days: 1
97+
- name: CDK deploy canary
98+
run: npm run cdk -w layers -- deploy --app cdk.out --context region=${{ matrix.region }} 'CanaryStack' --require-approval never --verbose --outputs-file cdk-outputs.json
9799
update_layer_arn_docs:
98100
needs: deploy-cdk-stack
99101
permissions:

Diff for: .github/workflows/run-e2e-tests.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
contents: read
2020
strategy:
2121
matrix:
22-
package: [logger, metrics, tracer, parameters]
22+
package: [logger, metrics, tracer, parameters, idempotency]
2323
version: [14, 16, 18]
2424
fail-fast: false
2525
steps:

Diff for: .gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ coverage
3333

3434
# Python virtual environments (for running mkdocs locally)
3535
venv
36+
.venv
3637

3738
# Static documentation site generated by Mkdocs
3839
site

Diff for: CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,13 @@
33
All notable changes to this project will be documented in this file.
44
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
55

6+
## [1.11.1](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v1.11.0...v1.11.1) (2023-07-11)
7+
8+
### Bug Fixes
9+
10+
- **docs:** fix alias in versions.json ([#1576](https://github.com/aws-powertools/powertools-lambda-typescript/issues/1576)) ([7198cbc](https://github.com/aws-powertools/powertools-lambda-typescript/commit/7198cbca28962e07486b90ecb4f265cafe28bf73))
11+
- **idempotency:** types, docs, and `makeIdempotent` function wrapper ([#1579](https://github.com/aws-powertools/powertools-lambda-typescript/issues/1579)) ([bba1c01](https://github.com/aws-powertools/powertools-lambda-typescript/commit/bba1c01a0b3f08e962568e1d0eb44d486829657b))
12+
613
# [1.11.0](https://github.com/aws-powertools/powertools-lambda-typescript/compare/v1.10.0...v1.11.0) (2023-06-29)
714

815
### Features

Diff for: docs/index.md

+34-34
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ You can use Powertools for AWS Lambda (TypeScript) in both TypeScript and JavaSc
2626

2727
You can install Powertools for AWS Lambda (TypeScript) using one of the following options:
2828

29-
* **Lambda Layer**: [**arn:aws:lambda:{region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:15**](#){: .copyMe}:clipboard:
29+
* **Lambda Layer**: [**arn:aws:lambda:{region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:16**](#){: .copyMe}:clipboard:
3030
* **npm**: [`npm install @aws-lambda-powertools/tracer @aws-lambda-powertools/metrics @aws-lambda-powertools/logger`](#){: .copyMe}:clipboard:
3131

3232
### Lambda Layer
@@ -41,31 +41,31 @@ You can include Powertools for AWS Lambda (TypeScript) Lambda Layer using [AWS L
4141

4242
| Region | Layer ARN |
4343
| ---------------- | ------------------------------------------------------------------------------------------------------------ |
44-
| `us-east-1` | [arn:aws:lambda:us-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
45-
| `us-east-2` | [arn:aws:lambda:us-east-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
46-
| `us-west-1` | [arn:aws:lambda:us-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
47-
| `us-west-2` | [arn:aws:lambda:us-west-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
48-
| `ap-south-1` | [arn:aws:lambda:ap-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
49-
| `ap-east-1` | [arn:aws:lambda:ap-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
50-
| `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
51-
| `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
52-
| `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
53-
| `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
54-
| `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
55-
| `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
56-
| `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
57-
| `eu-central-1` | [arn:aws:lambda:eu-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
58-
| `eu-central-2` | [arn:aws:lambda:eu-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
59-
| `eu-west-1` | [arn:aws:lambda:eu-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
60-
| `eu-west-2` | [arn:aws:lambda:eu-west-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
61-
| `eu-west-3` | [arn:aws:lambda:eu-west-3:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
62-
| `eu-north-1` | [arn:aws:lambda:eu-north-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
63-
| `eu-south-1` | [arn:aws:lambda:eu-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
64-
| `eu-south-2` | [arn:aws:lambda:eu-south-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
65-
| `ca-central-1` | [arn:aws:lambda:ca-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
66-
| `sa-east-1` | [arn:aws:lambda:sa-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
67-
| `af-south-1` | [arn:aws:lambda:af-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
68-
| `me-south-1` | [arn:aws:lambda:me-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:15](#){: .copyMe}:clipboard: |
44+
| `us-east-1` | [arn:aws:lambda:us-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
45+
| `us-east-2` | [arn:aws:lambda:us-east-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
46+
| `us-west-1` | [arn:aws:lambda:us-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
47+
| `us-west-2` | [arn:aws:lambda:us-west-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
48+
| `ap-south-1` | [arn:aws:lambda:ap-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
49+
| `ap-east-1` | [arn:aws:lambda:ap-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
50+
| `ap-northeast-1` | [arn:aws:lambda:ap-northeast-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
51+
| `ap-northeast-2` | [arn:aws:lambda:ap-northeast-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
52+
| `ap-northeast-3` | [arn:aws:lambda:ap-northeast-3:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
53+
| `ap-southeast-1` | [arn:aws:lambda:ap-southeast-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
54+
| `ap-southeast-2` | [arn:aws:lambda:ap-southeast-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
55+
| `ap-southeast-3` | [arn:aws:lambda:ap-southeast-3:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
56+
| `ap-southeast-4` | [arn:aws:lambda:ap-southeast-4:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
57+
| `eu-central-1` | [arn:aws:lambda:eu-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
58+
| `eu-central-2` | [arn:aws:lambda:eu-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
59+
| `eu-west-1` | [arn:aws:lambda:eu-west-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
60+
| `eu-west-2` | [arn:aws:lambda:eu-west-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
61+
| `eu-west-3` | [arn:aws:lambda:eu-west-3:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
62+
| `eu-north-1` | [arn:aws:lambda:eu-north-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
63+
| `eu-south-1` | [arn:aws:lambda:eu-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
64+
| `eu-south-2` | [arn:aws:lambda:eu-south-2:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
65+
| `ca-central-1` | [arn:aws:lambda:ca-central-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
66+
| `sa-east-1` | [arn:aws:lambda:sa-east-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
67+
| `af-south-1` | [arn:aws:lambda:af-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
68+
| `me-south-1` | [arn:aws:lambda:me-south-1:094274105915:layer:AWSLambdaPowertoolsTypeScript:16](#){: .copyMe}:clipboard: |
6969

7070
??? note "Click to expand and copy code snippets for popular frameworks"
7171

@@ -76,7 +76,7 @@ You can include Powertools for AWS Lambda (TypeScript) Lambda Layer using [AWS L
7676
Type: AWS::Serverless::Function
7777
Properties:
7878
Layers:
79-
- !Sub arn:aws:lambda:${AWS::Region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:15
79+
- !Sub arn:aws:lambda:${AWS::Region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:16
8080
```
8181

8282
If you use `esbuild` to bundle your code, make sure to exclude `@aws-lambda-powertools` from being bundled since the packages will be already present the Layer:
@@ -107,7 +107,7 @@ You can include Powertools for AWS Lambda (TypeScript) Lambda Layer using [AWS L
107107
hello:
108108
handler: lambda_function.lambda_handler
109109
layers:
110-
- arn:aws:lambda:${aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:15
110+
- arn:aws:lambda:${aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:16
111111
```
112112

113113
If you use `esbuild` to bundle your code, make sure to exclude `@aws-lambda-powertools` from being bundled since the packages will be already present the Layer:
@@ -139,7 +139,7 @@ You can include Powertools for AWS Lambda (TypeScript) Lambda Layer using [AWS L
139139
const powertoolsLayer = lambda.LayerVersion.fromLayerVersionArn(
140140
this,
141141
'PowertoolsLayer',
142-
`arn:aws:lambda:${cdk.Stack.of(this).region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:15`
142+
`arn:aws:lambda:${cdk.Stack.of(this).region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:16`
143143
);
144144
145145
new lambda.Function(this, 'Function', {
@@ -191,7 +191,7 @@ You can include Powertools for AWS Lambda (TypeScript) Lambda Layer using [AWS L
191191
role = ...
192192
handler = "index.handler"
193193
runtime = "nodejs16.x"
194-
layers = ["arn:aws:lambda:{aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:15"]
194+
layers = ["arn:aws:lambda:{aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:16"]
195195
source_code_hash = filebase64sha256("lambda_function_payload.zip")
196196
}
197197
```
@@ -209,7 +209,7 @@ You can include Powertools for AWS Lambda (TypeScript) Lambda Layer using [AWS L
209209

210210
const lambdaFunction = new aws.lambda.Function('function', {
211211
layers: [
212-
pulumi.interpolate`arn:aws:lambda:${aws.getRegionOutput().name}:094274105915:layer:AWSLambdaPowertoolsTypeScript:15`
212+
pulumi.interpolate`arn:aws:lambda:${aws.getRegionOutput().name}:094274105915:layer:AWSLambdaPowertoolsTypeScript:16`
213213
],
214214
code: new pulumi.asset.FileArchive('lambda_function_payload.zip'),
215215
tracingConfig: {
@@ -233,7 +233,7 @@ You can include Powertools for AWS Lambda (TypeScript) Lambda Layer using [AWS L
233233
? Do you want to configure advanced settings? Yes
234234
...
235235
? Do you want to enable Lambda layers for this function? Yes
236-
? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:{aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:15
236+
? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:{aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:16
237237
❯ amplify push -y
238238
239239
# Updating an existing function and add the layer
@@ -243,7 +243,7 @@ You can include Powertools for AWS Lambda (TypeScript) Lambda Layer using [AWS L
243243
- Name: <NAME-OF-FUNCTION>
244244
? Which setting do you want to update? Lambda layers configuration
245245
? Do you want to enable Lambda layers for this function? Yes
246-
? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:{aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:15
246+
? Enter up to 5 existing Lambda layer ARNs (comma-separated): arn:aws:lambda:{aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:16
247247
? Do you want to edit the local lambda function now? No
248248
```
249249

@@ -253,7 +253,7 @@ You can include Powertools for AWS Lambda (TypeScript) Lambda Layer using [AWS L
253253
Change {region} to your AWS region, e.g. `eu-west-1`
254254

255255
```bash title="AWS CLI"
256-
aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:15 --region {region}
256+
aws lambda get-layer-version-by-arn --arn arn:aws:lambda:{aws::region}:094274105915:layer:AWSLambdaPowertoolsTypeScript:16 --region {region}
257257
```
258258

259259
The pre-signed URL to download this Lambda Layer will be within `Location` key.
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { makeHandlerIdempotent } from '@aws-lambda-powertools/idempotency/middleware';
2+
import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb';
3+
import middy from '@middy/core';
4+
import type { Context } from 'aws-lambda';
5+
import type { Request, Response } from './types';
6+
7+
const persistenceStore = new DynamoDBPersistenceLayer({
8+
tableName: 'idempotencyTableName',
9+
keyAttr: 'idempotencyKey',
10+
expiryAttr: 'expiresAt',
11+
inProgressExpiryAttr: 'inProgressExpiresAt',
12+
statusAttr: 'currentStatus',
13+
dataAttr: 'resultData',
14+
validationKeyAttr: 'validationKey',
15+
});
16+
17+
export const handler = middy(
18+
async (_event: Request, _context: Context): Promise<Response> => {
19+
try {
20+
// ... create payment
21+
22+
return {
23+
paymentId: '1234567890',
24+
message: 'success',
25+
statusCode: 200,
26+
};
27+
} catch (error) {
28+
throw new Error('Error creating payment');
29+
}
30+
}
31+
).use(
32+
makeHandlerIdempotent({
33+
persistenceStore,
34+
})
35+
);

Diff for: docs/snippets/idempotency/makeHandlerIdempotent.ts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { randomUUID } from 'node:crypto';
2+
import { makeHandlerIdempotent } from '@aws-lambda-powertools/idempotency/middleware';
3+
import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb';
4+
import middy from '@middy/core';
5+
import type { Context } from 'aws-lambda';
6+
import type { Request, Response, SubscriptionResult } from './types';
7+
8+
const persistenceStore = new DynamoDBPersistenceLayer({
9+
tableName: 'idempotencyTableName',
10+
});
11+
12+
const createSubscriptionPayment = async (
13+
event: Request
14+
): Promise<SubscriptionResult> => {
15+
// ... create payment
16+
return {
17+
id: randomUUID(),
18+
productId: event.productId,
19+
};
20+
};
21+
22+
export const handler = middy(
23+
async (event: Request, _context: Context): Promise<Response> => {
24+
try {
25+
const payment = await createSubscriptionPayment(event);
26+
27+
return {
28+
paymentId: payment.id,
29+
message: 'success',
30+
statusCode: 200,
31+
};
32+
} catch (error) {
33+
throw new Error('Error creating payment');
34+
}
35+
}
36+
).use(
37+
makeHandlerIdempotent({
38+
persistenceStore,
39+
})
40+
);
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { randomUUID } from 'node:crypto';
2+
import {
3+
makeIdempotent,
4+
IdempotencyConfig,
5+
} from '@aws-lambda-powertools/idempotency';
6+
import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb';
7+
import type { Context } from 'aws-lambda';
8+
import type { Request, Response, SubscriptionResult } from './types';
9+
10+
const persistenceStore = new DynamoDBPersistenceLayer({
11+
tableName: 'idempotencyTableName',
12+
});
13+
const config = new IdempotencyConfig({});
14+
15+
const reportSubscriptionMetrics = async (
16+
_transactionId: string,
17+
_user: string
18+
): Promise<void> => {
19+
// ... send notification
20+
};
21+
22+
const createSubscriptionPayment = makeIdempotent(
23+
async (
24+
transactionId: string,
25+
event: Request
26+
): Promise<SubscriptionResult> => {
27+
// ... create payment
28+
return {
29+
id: transactionId,
30+
productId: event.productId,
31+
};
32+
},
33+
{
34+
persistenceStore,
35+
dataIndexArgument: 1,
36+
config,
37+
}
38+
);
39+
40+
export const handler = async (
41+
event: Request,
42+
context: Context
43+
): Promise<Response> => {
44+
config.registerLambdaContext(context);
45+
try {
46+
const transactionId = randomUUID();
47+
const payment = await createSubscriptionPayment(transactionId, event);
48+
49+
await reportSubscriptionMetrics(transactionId, event.user);
50+
51+
return {
52+
paymentId: payment.id,
53+
message: 'success',
54+
statusCode: 200,
55+
};
56+
} catch (error) {
57+
throw new Error('Error creating payment');
58+
}
59+
};

Diff for: docs/snippets/idempotency/makeIdempotentBase.ts

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { randomUUID } from 'node:crypto';
2+
import { makeIdempotent } from '@aws-lambda-powertools/idempotency';
3+
import { DynamoDBPersistenceLayer } from '@aws-lambda-powertools/idempotency/dynamodb';
4+
import type { Context } from 'aws-lambda';
5+
import type { Request, Response, SubscriptionResult } from './types';
6+
7+
const persistenceStore = new DynamoDBPersistenceLayer({
8+
tableName: 'idempotencyTableName',
9+
});
10+
11+
const createSubscriptionPayment = async (
12+
event: Request
13+
): Promise<SubscriptionResult> => {
14+
// ... create payment
15+
return {
16+
id: randomUUID(),
17+
productId: event.productId,
18+
};
19+
};
20+
21+
export const handler = makeIdempotent(
22+
async (event: Request, _context: Context): Promise<Response> => {
23+
try {
24+
const payment = await createSubscriptionPayment(event);
25+
26+
return {
27+
paymentId: payment.id,
28+
message: 'success',
29+
statusCode: 200,
30+
};
31+
} catch (error) {
32+
throw new Error('Error creating payment');
33+
}
34+
},
35+
{
36+
persistenceStore,
37+
}
38+
);

0 commit comments

Comments
 (0)