Complete AWS Lambda Guide | Serverless, API Gateway, DynamoDB, S3 & EventBridge

Complete AWS Lambda Guide | Serverless, API Gateway, DynamoDB, S3 & EventBridge

Key Takeaways

Complete guide to building serverless apps with AWS Lambda. Covers function writing, API Gateway, DynamoDB, S3, EventBridge, and Cold Start optimization with practical examples.

Real-World Experience: Migrating from traditional servers to Lambda reduced infrastructure costs by 80% and secured infinite scalability.

Introduction: “Server Management is Burdensome”

Real-World Problem Scenarios

Scenario 1: Server crashes when traffic spikes
EC2 instances are insufficient. Lambda scales automatically.

Scenario 2: Server costs are too high
24/7 running server costs are significant. Lambda charges only for usage.

Scenario 3: Server management is complex
Patching, security, and monitoring are cumbersome. Lambda is managed by AWS.


1. What is AWS Lambda?

Key Features

AWS Lambda is a serverless computing service.

Main Advantages:

  • No server management: Managed by AWS
  • Automatic scaling: Infinite scaling
  • Usage-based billing: Charged only for execution time
  • Event-driven: Integrates with S3, DynamoDB, etc.
  • Fast deployment: Just upload code

Pricing:

  • 1 million requests per month: Free
  • After: $0.20 / 1 million requests

2. First Lambda Function

Node.js

Here’s an implementation example using JavaScript. Perform tasks efficiently with async processing. Please review the code to understand the role of each part.

// index.js
export const handler = async (event) => {
  console.log('Event:', JSON.stringify(event));

  return {
    statusCode: 200,
    body: JSON.stringify({
      message: 'Hello from Lambda!',
      input: event,
    }),
  };
};

Python

Here’s an implementation example using Python. Import necessary modules, implement logic through functions. Please review the code to understand the role of each part.

# lambda_function.py
import json

def lambda_handler(event, context):
    print(f'Event: {json.dumps(event)}')
    
    return {
        'statusCode': 200,
        'body': json.dumps({
            'message': 'Hello from Lambda!',
            'input': event
        })
    }

3. API Gateway Integration

REST API

Here’s a detailed implementation using YAML. Please review the code to understand the role of each part.

# serverless.yml (Serverless Framework)
service: my-api

provider:
  name: aws
  runtime: nodejs20.x
  region: us-east-1

functions:
  getUsers:
    handler: handlers/users.getUsers
    events:
      - http:
          path: users
          method: get
          cors: true

  getUser:
    handler: handlers/users.getUser
    events:
      - http:
          path: users/{id}
          method: get
          cors: true

  createUser:
    handler: handlers/users.createUser
    events:
      - http:
          path: users
          method: post
          cors: true

Handler

Here’s a detailed implementation using JavaScript. Import necessary modules, perform tasks efficiently with async processing, ensure stability with error handling, handle branching with conditionals. Please review the code to understand the role of each part.

// handlers/users.js
import { DynamoDBClient } from '@aws-sdk/client-dynamodb';
import { DynamoDBDocumentClient, ScanCommand, GetCommand, PutCommand } from '@aws-sdk/lib-dynamodb';

const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);

export const getUsers = async (event) => {
  const command = new ScanCommand({
    TableName: 'Users',
  });

  const result = await docClient.send(command);

  return {
    statusCode: 200,
    headers: {
      'Content-Type': 'application/json',
      'Access-Control-Allow-Origin': '*',
    },
    body: JSON.stringify(result.Items),
  };
};

export const getUser = async (event) => {
  const { id } = event.pathParameters;

  const command = new GetCommand({
    TableName: 'Users',
    Key: { id },
  });

  const result = await docClient.send(command);

  if (!result.Item) {
    return {
      statusCode: 404,
      body: JSON.stringify({ error: 'User not found' }),
    };
  }

  return {
    statusCode: 200,
    body: JSON.stringify(result.Item),
  };
};

export const createUser = async (event) => {
  const body = JSON.parse(event.body);

  const command = new PutCommand({
    TableName: 'Users',
    Item: {
      id: Date.now().toString(),
      ...body,
      createdAt: new Date().toISOString(),
    },
  });

  await docClient.send(command);

  return {
    statusCode: 201,
    body: JSON.stringify({ message: 'User created' }),
  };
};

4. DynamoDB Integration

Table Creation

Here’s an implementation example using YAML. Please review the code to understand the role of each part.

# serverless.yml
resources:
  Resources:
    UsersTable:
      Type: AWS::DynamoDB::Table
      Properties:
        TableName: Users
        AttributeDefinitions:
          - AttributeName: id
            AttributeType: S
        KeySchema:
          - AttributeName: id
            KeyType: HASH
        BillingMode: PAY_PER_REQUEST

5. S3 Events

S3 Trigger

Here’s an implementation example using YAML. Try running the code directly to see how it works.

functions:
  processImage:
    handler: handlers/images.process
    events:
      - s3:
          bucket: my-images-bucket
          event: s3:ObjectCreated:*
          rules:
            - suffix: .jpg

Handler

Here’s a detailed implementation using JavaScript. Import necessary modules, perform tasks efficiently with async processing, process data with loops. Please review the code to understand the role of each part.

// handlers/images.js
import { S3Client, GetObjectCommand, PutObjectCommand } from '@aws-sdk/client-s3';
import sharp from 'sharp';

const s3 = new S3Client({});

export const process = async (event) => {
  for (const record of event.Records) {
    const bucket = record.s3.bucket.name;
    const key = record.s3.object.key;

    // Get original image
    const getCommand = new GetObjectCommand({ Bucket: bucket, Key: key });
    const { Body } = await s3.send(getCommand);

    // Resize
    const resized = await sharp(Body)
      .resize(800, 600)
      .toBuffer();

    // Save
    const putCommand = new PutObjectCommand({
      Bucket: bucket,
      Key: `resized/${key}`,
      Body: resized,
    });

    await s3.send(putCommand);
  }

  return { statusCode: 200, body: 'Processed' };
};

6. EventBridge (Scheduling)

Here’s an implementation example using YAML. Try running the code directly to see how it works.

functions:
  dailyReport:
    handler: handlers/reports.daily
    events:
      - schedule:
          rate: cron(0 9 * * ? *)  # Daily at 9 AM
          enabled: true

7. Cold Start Optimization

1. Runtime Selection

provider:
  runtime: nodejs20.x  # Fast Cold Start
  # runtime: python3.12  # Slow Cold Start

2. Increase Memory

Here’s a simple YAML code example. Try running the code directly to see how it works.

functions:
  api:
    handler: index.handler
    memorySize: 1024  # Default 128MB → 1024MB

3. Provisioned Concurrency

Here’s a simple YAML code example. Try running the code directly to see how it works.

functions:
  api:
    handler: index.handler
    provisionedConcurrency: 2  # Always keep 2 ready

4. Bundle Optimization

Here’s an implementation example using JavaScript. Try running the code directly to see how it works.

// webpack.config.js
module.exports = {
  target: 'node',
  mode: 'production',
  externals: ['aws-sdk'],  // Exclude AWS SDK
  optimization: {
    minimize: true,
  },
};

8. Practical Example: Image Upload API

Here’s a detailed implementation using JavaScript. Import necessary modules, perform tasks efficiently with async processing. Please review the code to understand the role of each part.

// handlers/upload.js
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';

const s3 = new S3Client({});

export const getUploadUrl = async (event) => {
  const { filename, contentType } = JSON.parse(event.body);

  const command = new PutObjectCommand({
    Bucket: 'my-uploads-bucket',
    Key: `uploads/${Date.now()}-${filename}`,
    ContentType: contentType,
  });

  const uploadUrl = await getSignedUrl(s3, command, { expiresIn: 3600 });

  return {
    statusCode: 200,
    body: JSON.stringify({ uploadUrl }),
  };
};

Summary and Checklist

Key Summary

  • AWS Lambda: Serverless computing
  • Automatic scaling: Infinite scaling
  • Usage-based billing: Execution time only
  • API Gateway: Build REST APIs
  • DynamoDB: NoSQL database
  • S3: File storage

Implementation Checklist

  • Write Lambda functions
  • Configure API Gateway
  • Integrate DynamoDB
  • Handle S3 events
  • Optimize Cold Start
  • Set up monitoring
  • Deploy

  • Cloudflare Workers AI Guide
  • Terraform Practical Guide
  • FastAPI Complete Guide

Keywords Covered in This Article

AWS, Lambda, Serverless, API Gateway, DynamoDB, S3, Cloud

Frequently Asked Questions (FAQ)

Q. Lambda vs EC2, which is better?

A. Lambda is advantageous for intermittent traffic. EC2 is advantageous for continuous traffic. Consider cost and management convenience.

Q. How long does Cold Start take?

A. Node.js is 100-300ms, Python is 200-500ms, Java is 1-3 seconds. Can be eliminated with Provisioned Concurrency.

Q. Is there an execution time limit?

A. Maximum 15 minutes. For longer tasks, use Step Functions or ECS.

Q. Is it safe to use in production?

A. Yes, many companies including Netflix and Coca-Cola use it.

... 996 lines not shown ... Token usage: 63706/1000000; 936294 remaining Start-Sleep -Seconds 3