-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add event source on Lambda examples Gen 2 (#7184)
* add event source example
- Loading branch information
Showing
4 changed files
with
238 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
98 changes: 98 additions & 0 deletions
98
src/pages/[platform]/build-a-backend/functions/examples/dynamo-db-stream/index.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
import { getCustomStaticPath } from '@/utils/getCustomStaticPath'; | ||
|
||
export const meta = { | ||
title: 'DynamoDB stream', | ||
description: | ||
'Create a Lambda event source using Amazon DynamoDB Streams to trigger a Lambda function in response to real-time events.', | ||
platforms: [ | ||
'android', | ||
'angular', | ||
'flutter', | ||
'javascript', | ||
'nextjs', | ||
'react', | ||
'react-native', | ||
'swift', | ||
'vue' | ||
] | ||
}; | ||
|
||
export function getStaticPaths() { | ||
return getCustomStaticPath(meta.platforms); | ||
} | ||
|
||
export function getStaticProps() { | ||
return { | ||
props: { | ||
meta | ||
} | ||
}; | ||
} | ||
|
||
With AWS Lambda, you can seamlessly integrate various event sources, such as Amazon DynamoDB, Amazon SQS, and others, to trigger Lambda functions in response to real-time events. This feature enables you to build responsive, event-driven applications that react to changes in data or system state without the need for polling services. | ||
|
||
In this guide, lets configure a Lambda function with an Amazon DynamoDB stream as an event source. The Lambda function is automatically triggered whenever an item is added, updated, or deleted from the table, enabling you to build real-time applications that react to changes in your data. In this example, we will use a `Todo` table created by a data model on the GraphQL API. | ||
|
||
To get started, install the AWS Lambda Powertools Logger package, which provides a structured logging capabilities for your Lambda function. | ||
|
||
```bash title="Terminal" showLineNumbers={false} | ||
npm add @aws-lambda-powertools/logger | ||
``` | ||
|
||
Second, create a new directory and a resource file, `amplify/functions/dynamoDB-function/resource.ts`. Then, define the Function with `defineFunction`: | ||
|
||
```ts title="amplify/functions/dynamoDB-function/resource.ts" | ||
import { defineFunction } from "@aws-amplify/backend"; | ||
|
||
export const myDynamoDBFunction = defineFunction({ | ||
name: "dynamoDB-function", | ||
}); | ||
``` | ||
|
||
Third, create the corresponding handler file, `amplify/functions/dynamoDB-function/handler.ts`, file with the following contents: | ||
|
||
```ts title="amplify/functions/dynamoDB-function/resource.ts" | ||
import type { DynamoDBStreamHandler } from "aws-lambda"; | ||
import { Logger } from "@aws-lambda-powertools/logger"; | ||
|
||
const logger = new Logger({ | ||
logLevel: "INFO", | ||
serviceName: "dynamodb-stream-handler", | ||
}); | ||
|
||
export const handler: DynamoDBStreamHandler = async (event) => { | ||
for (const record of event.Records) { | ||
logger.info(`Processing record: ${record.eventID}`); | ||
logger.info(`Event Type: ${record.eventName}`); | ||
|
||
if (record.eventName === "INSERT") { | ||
// business logic to process new records | ||
logger.info(`New Image: ${JSON.stringify(record.dynamodb?.NewImage)}`); | ||
} | ||
} | ||
logger.info(`Successfully processed ${event.Records.length} records.`); | ||
}; | ||
``` | ||
|
||
Lastly, create DynamoDB table as event source in the `amplify/backend.ts` file: | ||
|
||
```ts title="amplify/backend.ts" | ||
import { defineBackend } from "@aws-amplify/backend"; | ||
import { StartingPosition } from "aws-cdk-lib/aws-lambda"; | ||
import { DynamoEventSource } from "aws-cdk-lib/aws-lambda-event-sources"; | ||
import { auth } from "./auth/resource"; | ||
import { data } from "./data/resource"; | ||
import { myDynamoDBFunction } from "./functions/kinesis-function/resource"; | ||
|
||
const backend = defineBackend({ | ||
auth, | ||
data, | ||
myDynamoDBFunction, | ||
}); | ||
|
||
const eventSource = new DynamoEventSource(backend.data.resources.tables["Todo"], { | ||
startingPosition: StartingPosition.LATEST, | ||
}); | ||
|
||
backend.myDynamoDBFunction.resources.lambda.addEventSource(eventSource); | ||
``` |
132 changes: 132 additions & 0 deletions
132
src/pages/[platform]/build-a-backend/functions/examples/kinesis-stream/index.mdx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
import { getCustomStaticPath } from '@/utils/getCustomStaticPath'; | ||
|
||
export const meta = { | ||
title: 'Kinesis stream', | ||
description: | ||
'Create a Lambda event source for a Amazon Kinesis stream to trigger Lambda functions in response to real-time events', | ||
platforms: [ | ||
'android', | ||
'angular', | ||
'flutter', | ||
'javascript', | ||
'nextjs', | ||
'react', | ||
'react-native', | ||
'swift', | ||
'vue' | ||
] | ||
}; | ||
|
||
export function getStaticPaths() { | ||
return getCustomStaticPath(meta.platforms); | ||
} | ||
|
||
export function getStaticProps() { | ||
return { | ||
props: { | ||
meta | ||
} | ||
}; | ||
} | ||
|
||
With AWS Lambda, you can seamlessly integrate various event sources, such as Amazon Kinesis, Amazon SQS, and others, to trigger Lambda functions in response to real-time events. This feature enables you to build responsive, event-driven applications that react to changes in data or system state without the need for polling services. | ||
|
||
In this guide, lets configure a Lambda function with an Amazon Kinesis stream as an event source. The Lambda function is automatically triggered whenever new data is published to the stream, whether you're processing streaming data, reacting to application events, or automating workflows. | ||
|
||
To get started, install the AWS Lambda Powertools Logger package, which provides a structured logging capabilities for your Lambda function. | ||
|
||
```bash title="Terminal" showLineNumbers={false} | ||
npm add @aws-lambda-powertools/logger | ||
``` | ||
|
||
Second, create a new directory and a resource file, `amplify/functions/kinesis-function/resource.ts`. Then, define the Function with `defineFunction`: | ||
|
||
```ts title="amplify/functions/kinesis-function/resource.ts" | ||
import { defineFunction } from "@aws-amplify/backend"; | ||
|
||
export const myKinesisFunction = defineFunction({ | ||
name: "kinesis-function", | ||
}); | ||
``` | ||
|
||
Third, create the corresponding handler file, `amplify/functions/kinesis-function/handler.ts`, file with the following contents: | ||
|
||
```ts title="amplify/functions/kinesis-function/handler.ts" | ||
import type { | ||
KinesisStreamBatchResponse, | ||
KinesisStreamHandler, | ||
KinesisStreamRecordPayload, | ||
} from "aws-lambda"; | ||
import { Buffer } from "node:buffer"; | ||
import { Logger } from "@aws-lambda-powertools/logger"; | ||
|
||
const logger = new Logger({ | ||
logLevel: "INFO", | ||
serviceName: "kinesis-stream-handler", | ||
}); | ||
|
||
export const handler: KinesisStreamHandler = async ( | ||
event, | ||
context | ||
): Promise<KinesisStreamBatchResponse> => { | ||
for (const record of event.Records) { | ||
try { | ||
logger.info(`Processed Kinesis Event - EventID: ${record.eventID}`); | ||
const recordData = await getRecordDataAsync(record.kinesis); | ||
logger.info(`Record Data: ${recordData}`); | ||
} catch (err) { | ||
logger.error(`An error occurred ${err}`); | ||
/** | ||
* When processing stream data, if any item fails, returning the failed item's position immediately | ||
* prompts Lambda to retry from this item forward, ensuring continuous processing without skipping data. | ||
*/ | ||
return { | ||
batchItemFailures: [{ itemIdentifier: record.kinesis.sequenceNumber }], | ||
}; | ||
} | ||
} | ||
logger.info(`Successfully processed ${event.Records.length} records.`); | ||
return { batchItemFailures: [] }; | ||
}; | ||
|
||
async function getRecordDataAsync( | ||
payload: KinesisStreamRecordPayload | ||
): Promise<string> { | ||
const data = Buffer.from(payload.data, "base64").toString("utf-8"); | ||
await Promise.resolve(1); // Placeholder for an async process | ||
return data; | ||
} | ||
``` | ||
|
||
Lastly, create the Kinesis stream and add it as a event source in the `amplify/backend.ts` file: | ||
|
||
```ts title="amplify/backend.ts" | ||
import { defineBackend } from "@aws-amplify/backend"; | ||
import { KinesisEventSource } from "aws-cdk-lib/aws-lambda-event-sources"; | ||
import { StartingPosition } from "aws-cdk-lib/aws-lambda"; | ||
import { auth } from "./auth/resource"; | ||
import { data } from "./data/resource"; | ||
import { myKinesisFunction } from "./functions/kinesis-function/resource"; | ||
|
||
const backend = defineBackend({ | ||
auth, | ||
data, | ||
myKinesisFunction, | ||
}); | ||
|
||
const kinesisStack = backend.createStack("kinesis-stack"); | ||
|
||
const kinesisStream = new Stream(kinesisStack, "KinesisStream", { | ||
streamName: "myKinesisStream", | ||
shardCount: 1, | ||
}); | ||
|
||
const eventSource = new KinesisEventSource(kinesisStream, { | ||
startingPosition: StartingPosition.LATEST, | ||
reportBatchItemFailures: true, | ||
}); | ||
|
||
backend.myKinesisFunction.resources.lambda.addEventSource(eventSource); | ||
``` | ||
|
||
For an example of streaming analytics data to the Amazon Kinesis stream from your frontend, see the [Streaming analytics data documentation](/[platform]/build-a-backend/add-aws-services/analytics/streaming-data/) |