Lambda: Event Sources & Integrations
Lambda can be triggered synchronously (caller waits for response), asynchronously (fire and forget), or via polling (Lambda polls the source).
Invocation Types
Synchronous: API Gateway, ALB, Function URL, Cognito, Alexa — caller waits, errors returned to caller
Asynchronous: S3, SNS, EventBridge, SES, CloudFormation — event queued, Lambda retries on error (2 times)
Poll-based: SQS, Kinesis, DynamoDB Streams, Kafka — Lambda polls, processes batches
API Gateway & Function URLs
// HTTP API (API GW v2) event structure
export const handler = async (event) => {
const { method, path, queryStringParameters, headers, body } = event;
const parsedBody = body ? JSON.parse(body) : null;
return {
statusCode: 200,
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Origin': '*',
},
body: JSON.stringify({ method, path, data: parsedBody }),
};
};# Create Function URL (no API GW needed, simpler)
aws lambda create-function-url-config \
--function-name my-api-handler \
--auth-type NONE \
--cors '{
"AllowOrigins": ["https://myapp.com"],
"AllowMethods": ["GET","POST"],
"AllowHeaders": ["Content-Type"]
}'
# Output: https://<url-id>.lambda-url.eu-west-1.on.aws/SQS Trigger
Lambda polls SQS and processes messages in batches. On failure, the batch is retried. Configure a DLQ on the SQS queue for messages that consistently fail.
// SQS event structure
export const handler = async (event) => {
const results = [];
for (const record of event.Records) {
const message = JSON.parse(record.body);
try {
await processMessage(message);
results.push({ itemIdentifier: record.messageId });
} catch (err) {
console.error('Failed to process:', record.messageId, err);
// Don't throw — let successful messages be deleted
// Only failed ones go back to queue (report batch item failures)
}
}
};
// Better: report partial batch failures
export const handler = async (event) => {
const failures = [];
for (const record of event.Records) {
try {
await processMessage(JSON.parse(record.body));
} catch (err) {
failures.push({ itemIdentifier: record.messageId });
}
}
return { batchItemFailures: failures };
};# Create SQS trigger
aws lambda create-event-source-mapping \
--function-name my-worker \
--event-source-arn arn:aws:sqs:eu-west-1:123:my-queue \
--batch-size 10 \
--maximum-batching-window-in-seconds 5 \
--function-response-types ReportBatchItemFailuresS3 Event Trigger
// S3 event structure
export const handler = async (event) => {
for (const record of event.Records) {
const bucket = record.s3.bucket.name;
const key = decodeURIComponent(record.s3.object.key.replace(/+/g, ' '));
const size = record.s3.object.size;
const eventType = record.eventName; // ObjectCreated:Put, ObjectRemoved:Delete, etc.
console.log(`Event: ${eventType} | ${bucket}/${key} (${size} bytes)`);
await processUploadedFile(bucket, key);
}
};EventBridge (Scheduled & Event-Driven)
# Schedule Lambda every 5 minutes (cron)
aws events put-rule \
--name cleanup-job \
--schedule-expression "rate(5 minutes)" \
--state ENABLED
aws events put-targets \
--rule cleanup-job \
--targets Id=1,Arn=arn:aws:lambda:eu-west-1:123:function:cleanup
# Grant EventBridge permission to invoke Lambda
aws lambda add-permission \
--function-name cleanup \
--statement-id EventBridgeInvoke \
--action lambda:InvokeFunction \
--principal events.amazonaws.com \
--source-arn arn:aws:events:eu-west-1:123:rule/cleanup-jobLambda Destinations
Destinations route async invocation results to SNS, SQS, EventBridge, or another Lambda — for both success and failure. Preferred over DLQ for async functions.
aws lambda put-function-event-invoke-config \
--function-name my-processor \
--maximum-retry-attempts 2 \
--destination-config '{
"OnSuccess": {
"Destination": "arn:aws:sqs:eu-west-1:123:success-queue"
},
"OnFailure": {
"Destination": "arn:aws:sqs:eu-west-1:123:dead-letter-queue"
}
}'Keep your own version of these notes — editable, searchable, and organised by your stack.
Start free