Skip to content

Commit 01f8a68

Browse files
authored
feat(event-handler): AppSync Events resolver (#3858)
1 parent 68fa1eb commit 01f8a68

Some content is hidden

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

47 files changed

+2885
-70
lines changed

docs/features/event-handler/appsync-events.md

Lines changed: 410 additions & 0 deletions
Large diffs are not rendered by default.

docs/features/index.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,14 @@ description: Features of Powertools for AWS Lambda
3131

3232
[:octicons-arrow-right-24: Read more](./metrics.md)
3333

34+
- __Event Handler - AppSync Events__
35+
36+
---
37+
38+
Event Handler for AWS AppSync real-time events
39+
40+
[:octicons-arrow-right-24: Read more](./event-handler/appsync-events.md)
41+
3442
- __Parameters__
3543

3644
---

docs/index.md

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,18 @@ You can use Powertools for AWS Lambda in both TypeScript and JavaScript code bas
4242

4343
Powertools for AWS Lambda (TypeScript) is built as a modular toolkit, so you can pick and choose the utilities you want to use. The following table lists the available utilities, and links to their documentation.
4444

45-
| Utility | Description |
46-
| -------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- ------------------------------- |
47-
| [Tracer](./features/tracer.md) | Decorators and utilities to trace Lambda function handlers, and both synchronous and asynchronous functions |
48-
| [Logger](./features/logger.md) | Structured logging made easier, and a middleware to enrich structured logging with key Lambda context details |
49-
| [Metrics](./features/metrics.md) | Custom Metrics created asynchronously via CloudWatch Embedded Metric Format (EMF) |
50-
| [Parameters](./features/parameters.md) | High-level functions to retrieve one or more parameters from AWS SSM Parameter Store, AWS Secrets Manager, AWS AppConfig, and Amazon DynamoDB |
51-
| [Idempotency](./features/idempotency.md) | Class method decorator, Middy middleware, and function wrapper to make your Lambda functions idempotent and prevent duplicate execution based on payload content. |
52-
| [Batch Processing](./features/batch.md) | Utility to handle partial failures when processing batches from Amazon SQS, Amazon Kinesis Data Streams, and Amazon DynamoDB Streams. |
53-
| [JMESPath Functions](./features/jmespath.md) | Built-in JMESPath functions to easily deserialize common encoded JSON payloads in Lambda functions. |
54-
| [Parser](./features/parser.md) | Utility to parse and validate AWS Lambda event payloads using Zod, a TypeScript-first schema declaration and validation library. |
55-
| [Validation](./features/validation.md) | JSON Schema validation for events and responses, including JMESPath support to unwrap events before validation. |
45+
| Utility | Description |
46+
| ---------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
47+
| [Tracer](./features/tracer.md) | Decorators and utilities to trace Lambda function handlers, and both synchronous and asynchronous functions |
48+
| [Logger](./features/logger.md) | Structured logging made easier, and a middleware to enrich structured logging with key Lambda context details |
49+
| [Metrics](./features/metrics.md) | Custom Metrics created asynchronously via CloudWatch Embedded Metric Format (EMF) |
50+
| [Event Handler - AppSync Events](./features/event-handler/appsync-events.md) | Event Handler for AWS AppSync real-time events |
51+
| [Parameters](./features/parameters.md) | High-level functions to retrieve one or more parameters from AWS SSM Parameter Store, AWS Secrets Manager, AWS AppConfig, and Amazon DynamoDB |
52+
| [Idempotency](./features/idempotency.md) | Class method decorator, Middy middleware, and function wrapper to make your Lambda functions idempotent and prevent duplicate execution based on payload content. |
53+
| [Batch Processing](./features/batch.md) | Utility to handle partial failures when processing batches from Amazon SQS, Amazon Kinesis Data Streams, and Amazon DynamoDB Streams. |
54+
| [JMESPath Functions](./features/jmespath.md) | Built-in JMESPath functions to easily deserialize common encoded JSON payloads in Lambda functions. |
55+
| [Parser](./features/parser.md) | Utility to parse and validate AWS Lambda event payloads using Zod, a TypeScript-first schema declaration and validation library. |
56+
| [Validation](./features/validation.md) | JSON Schema validation for events and responses, including JMESPath support to unwrap events before validation. |
5657

5758
## Examples
5859

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { AppSyncEventsResolver } from '@aws-lambda-powertools/event-handler/appsync-events';
2+
import type { Context } from 'aws-lambda';
3+
4+
const app = new AppSyncEventsResolver();
5+
6+
app.onPublish('/*', (payload, event, context) => {
7+
const { headers } = event.request; // (1)!
8+
const { awsRequestId } = context;
9+
10+
// your business logic here
11+
12+
return payload;
13+
});
14+
15+
export const handler = async (event: unknown, context: Context) =>
16+
await app.resolve(event, context);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { AppSyncEventsResolver } from '@aws-lambda-powertools/event-handler/appsync-events';
2+
import {
3+
BatchWriteItemCommand,
4+
DynamoDBClient,
5+
type WriteRequest,
6+
} from '@aws-sdk/client-dynamodb';
7+
import { marshall } from '@aws-sdk/util-dynamodb';
8+
import type { Context } from 'aws-lambda';
9+
10+
const ddbClient = new DynamoDBClient();
11+
const app = new AppSyncEventsResolver();
12+
13+
app.onPublish(
14+
'/default/foo/*',
15+
async (payloads) => {
16+
const writeOperations: WriteRequest[] = [];
17+
for (const payload of payloads) {
18+
writeOperations.push({
19+
PutRequest: {
20+
Item: marshall(payload),
21+
},
22+
});
23+
}
24+
await ddbClient.send(
25+
new BatchWriteItemCommand({
26+
RequestItems: {
27+
'your-table-name': writeOperations,
28+
},
29+
})
30+
);
31+
32+
return payloads;
33+
},
34+
{ aggregate: true }
35+
);
36+
37+
export const handler = async (event: unknown, context: Context) =>
38+
app.resolve(event, context);
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { AppSyncEventsResolver } from '@aws-lambda-powertools/event-handler/appsync-events';
2+
import type { OnPublishAggregateOutput } from '@aws-lambda-powertools/event-handler/types';
3+
import { Logger } from '@aws-lambda-powertools/logger';
4+
import type { Context } from 'aws-lambda';
5+
6+
const logger = new Logger({
7+
serviceName: 'serverlessAirline',
8+
logLevel: 'INFO',
9+
});
10+
const app = new AppSyncEventsResolver();
11+
12+
app.onPublish(
13+
'/default/foo/*',
14+
async (payloads) => {
15+
const returnValues: OnPublishAggregateOutput<{
16+
processed: boolean;
17+
original_payload: unknown;
18+
}> = [];
19+
try {
20+
for (const payload of payloads) {
21+
returnValues.push({
22+
id: payload.id,
23+
payload: { processed: true, original_payload: payload },
24+
});
25+
}
26+
} catch (error) {
27+
logger.error('Error processing payloads', { error });
28+
throw error;
29+
}
30+
31+
return returnValues;
32+
},
33+
{ aggregate: true }
34+
);
35+
36+
export const handler = async (event: unknown, context: Context) =>
37+
app.resolve(event, context);
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { AppSyncEventsResolver } from '@aws-lambda-powertools/event-handler/appsync-events';
2+
import { Logger } from '@aws-lambda-powertools/logger';
3+
import type { Context } from 'aws-lambda';
4+
5+
const logger = new Logger({
6+
serviceName: 'serverlessAirline',
7+
logLevel: 'DEBUG',
8+
});
9+
const app = new AppSyncEventsResolver({ logger });
10+
11+
app.onPublish('/default/foo', (payload) => {
12+
return payload;
13+
});
14+
15+
export const handler = async (event: unknown, context: Context) =>
16+
await app.resolve(event, context);
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { AppSyncEventsResolver } from '@aws-lambda-powertools/event-handler/appsync-events';
2+
import type { OnPublishAggregateOutput } from '@aws-lambda-powertools/event-handler/types';
3+
import type { Context } from 'aws-lambda';
4+
5+
const app = new AppSyncEventsResolver();
6+
7+
app.onPublish(
8+
'/default/foo/*',
9+
async (payloads) => {
10+
const returnValues: OnPublishAggregateOutput<{
11+
processed: boolean;
12+
original_payload: unknown;
13+
}> = [];
14+
for (const payload of payloads) {
15+
try {
16+
returnValues.push({
17+
id: payload.id,
18+
payload: { processed: true, original_payload: payload },
19+
});
20+
} catch (error) {
21+
returnValues.push({
22+
id: payload.id,
23+
error: `${error.name} - ${error.message}`,
24+
});
25+
}
26+
}
27+
28+
return returnValues;
29+
},
30+
{ aggregate: true }
31+
);
32+
33+
export const handler = async (event: unknown, context: Context) =>
34+
app.resolve(event, context);
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { AppSyncEventsResolver } from '@aws-lambda-powertools/event-handler/appsync-events';
2+
import { Logger } from '@aws-lambda-powertools/logger';
3+
import type { Context } from 'aws-lambda';
4+
5+
const logger = new Logger({
6+
serviceName: 'appsync-events',
7+
logLevel: 'DEBUG',
8+
});
9+
const app = new AppSyncEventsResolver();
10+
11+
app.onPublish('/default/foo', (payload) => {
12+
try {
13+
return payload;
14+
} catch (error) {
15+
logger.error('Error processing event', { error });
16+
throw error;
17+
}
18+
});
19+
20+
export const handler = async (event: unknown, context: Context) =>
21+
app.resolve(event, context);
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { AppSyncEventsResolver } from '@aws-lambda-powertools/event-handler/appsync-events';
2+
import type { Context } from 'aws-lambda';
3+
4+
const app = new AppSyncEventsResolver();
5+
6+
app.onPublish('/default/foo', (payload) => {
7+
return {
8+
processed: true,
9+
original_payload: payload,
10+
};
11+
});
12+
13+
export const handler = async (event: unknown, context: Context) =>
14+
app.resolve(event, context);

0 commit comments

Comments
 (0)