Docs
/
AWS Cloud
Chapter 9

09 — API Gateway

What is API Gateway?

Managed service to create, deploy, and manage REST, HTTP, and WebSocket APIs at any scale.

Client → API Gateway → Lambda / EC2 / Any HTTP endpoint
              │
              ├── Authentication
              ├── Rate Limiting
              ├── Request Validation
              ├── Caching
              └── CORS

API Types

TypeProtocolBest ForCost
HTTP APIHTTPSimple Lambda proxy, low cost~$1/million requests
REST APIHTTPFull features (caching, WAF, validation)~$3.50/million
WebSocket APIWebSocketReal-time (chat, notifications)~$1/million messages

> Use HTTP API unless you need REST API-specific features (caching, request validation, resource policies).


REST API Example

# SAM template
Resources:
  Api:
    Type: AWS::Serverless::Api
    Properties:
      StageName: prod
      Cors:
        AllowOrigin: "'https://myapp.com'"
        AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'"
        AllowHeaders: "'Content-Type,Authorization'"

  GetUsersFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: handlers/users.getAll
      Events:
        GetUsers:
          Type: Api
          Properties:
            RestApiId: !Ref Api
            Path: /users
            Method: GET

  CreateUserFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: handlers/users.create
      Events:
        CreateUser:
          Type: Api
          Properties:
            RestApiId: !Ref Api
            Path: /users
            Method: POST

Stages & Deployment

API Gateway stages:
  /dev   → points to dev Lambda aliases
  /staging → points to staging aliases
  /prod  → points to prod aliases

Each stage has its own URL:
  https://abc123.execute-api.us-east-1.amazonaws.com/dev
  https://abc123.execute-api.us-east-1.amazonaws.com/prod

Custom domain:
  https://api.myapp.com → maps to prod stage

Authorizers

TypeHow It Works
CognitoValidates JWT from Cognito User Pool
Lambda AuthorizerCustom auth logic (API keys, custom tokens)
IAMAWS SigV4 signing (service-to-service)
// Lambda Authorizer
export const authorizer = async (event: any) => {
  const token = event.authorizationToken; // "Bearer xxx"
  const decoded = verifyJwt(token.replace('Bearer ', ''));

  return {
    principalId: decoded.sub,
    policyDocument: {
      Version: '2012-10-17',
      Statement: [{
        Action: 'execute-api:Invoke',
        Effect: decoded ? 'Allow' : 'Deny',
        Resource: event.methodArn,
      }],
    },
    context: { userId: decoded.sub, role: decoded.role },
  };
};

Throttling & Rate Limiting

Account-level:  10,000 requests/sec (default)
Stage-level:    Can set per-stage limits
Method-level:   Can set per-route limits

Usage Plans:
  Basic:    100 requests/day,  10/sec burst
  Pro:      10,000 requests/day, 100/sec burst

API Keys:
  Tied to usage plans for per-client throttling

Request Validation

{
  "type": "object",
  "required": ["name", "email"],
  "properties": {
    "name": { "type": "string", "minLength": 1 },
    "email": { "type": "string", "format": "email" },
    "age": { "type": "integer", "minimum": 0 }
  }
}

Rejects invalid requests before invoking Lambda — saves cost.


CORS Configuration

// In Lambda response (HTTP API auto-handles if configured)
return {
  statusCode: 200,
  headers: {
    'Access-Control-Allow-Origin': 'https://myapp.com',
    'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE',
    'Access-Control-Allow-Headers': 'Content-Type,Authorization',
  },
  body: JSON.stringify(data),
};

Key Takeaways

  • HTTP API for most use cases (cheaper, simpler); REST API for advanced features
  • Use Cognito Authorizer for user-facing APIs, Lambda Authorizer for custom auth
  • Enable request validation to reject bad requests before hitting Lambda
  • Configure usage plans + API keys for per-client rate limiting
  • Use custom domains with Route 53 for production APIs
  • Always configure CORS for browser-based clients