Lambda
06 / 08

Event Sources & Integrations

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 ReportBatchItemFailures

S3 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-job

Lambda 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