DevOps & Cloud

AWS API Gateway

TOKEN

Panduan lengkap AWS API Gateway β€” REST API, HTTP API, stages, throttling, authorizers, request/response mapping, dan best practices untuk API management di AWS

1. Pengenalan API Gateway

Amazon API Gateway adalah layanan fully managed yang memungkinkan developer untuk membuat, mempublish, memelihara, memantau, dan mengamankan API pada skala berapa pun. API Gateway bertindak sebagai "front door" bagi aplikasi untuk mengakses backend β€” baik itu Lambda functions, EC2 instances, ECS services, atau layanan AWS lainnya.

API Gateway menangani semua tugas yang terkait dengan menerima dan memproses hingga ratusan ribu panggilan API secara simultan β€” termasuk traffic management, authorization, access control, monitoring, dan API version management.

Mengapa API Gateway Penting?

Fitur Penjelasan
Centralized Entry PointSatu endpoint untuk semua API β€” konsisten, mudah dikelola
AuthenticationIntegrasi dengan Cognito, IAM, Lambda Authorizer, OIDC
ThrottlingRate limiting per client, per API, per method
CachingResponse caching built-in untuk mengurangi beban backend
MonitoringCloudWatch integration untuk metrics dan logging
TransformationsRequest/response transformation dan mapping
WebSocketSupport untuk real-time bidirectional communication
CostPay-per-request β€” tidak ada biaya minimum atau commitment
Diagram: API Gateway Architecture
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚          β”‚     β”‚            AWS API GATEWAY                    β”‚
β”‚  Client  │────►│  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚ (Mobile/ β”‚     β”‚  β”‚ Auth &   β”‚ β”‚ Throttle β”‚ β”‚  Transform   β”‚ β”‚
β”‚  Web/    │◄────│  β”‚ Authorizeβ”‚ β”‚ & Cache  β”‚ β”‚  & Mapping   β”‚ β”‚
β”‚  IoT)    β”‚     β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                    β”‚
                    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                    β”‚               β”‚               β”‚
                    β–Ό               β–Ό               β–Ό
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚  Lambda   β”‚  β”‚   ECS    β”‚  β”‚   HTTP       β”‚
              β”‚ Function  β”‚  β”‚ Service  β”‚  β”‚   Endpoint   β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
πŸ’‘ Tips

API Gateway + Lambda adalah kombinasi serverless paling populer di AWS. Anda tidak perlu mengelola server sama sekali β€” API Gateway menangani routing dan Lambda mengeksekusi logic. Bayar hanya ketika ada request.

2. REST API vs HTTP API

API Gateway menyediakan dua jenis API: REST API (API Gateway v1) dan HTTP API (API Gateway v2). Memahami perbedaan keduanya sangat penting untuk memilih jenis yang tepat untuk use case Anda.

Perbandingan REST API vs HTTP API

Fitur REST API HTTP API
HargaπŸ”΄ $3.50 per juta request🟒 $1.00 per juta request
Latency🟑 Sedang🟒 Rendah (~60% lebih cepat)
Caching🟒 Built-inπŸ”΄ Tidak ada
WAF Integration🟒 Ya🟑 Terbatas
Request Validation🟒 YaπŸ”΄ Tidak
Usage Plans & API Keys🟒 YaπŸ”΄ Tidak
Transformations🟒 VTL Mapping Templates🟑 Terbatas
JWT AuthorizerπŸ”΄ Tidak🟒 Built-in
Lambda Authorizer🟒 Ya🟒 Ya
Private API🟒 YaπŸ”΄ Tidak
WebSocketπŸ”΄ Tidak🟒 Ya
⚠️ Peringatan

Gunakan HTTP API untuk use case sederhana yang membutuhkan performa tinggi dan harga rendah. Gunakan REST API ketika Anda butuh fitur lanjutan seperti caching, request validation, WAF, atau private API.

3. Membuat REST API

Membuat REST API di API Gateway melibatkan beberapa langkah: membuat API, mendefinisikan resource dan method, mengintegrasikan dengan backend, dan mendeploy.

Membuat API dengan AWS CLI

Bash
# Membuat REST API baru
API_ID=$(aws apigateway create-rest-api \
  --name "My API" \
  --description "My first API Gateway" \
  --endpoint-configuration types=REGIONAL \
  --query 'id' --output text)

echo "API ID: $API_ID"

# Dapatkan root resource ID
ROOT_ID=$(aws apigateway get-resources \
  --rest-api-id $API_ID \
  --query 'items[0].id' --output text)

# Membuat resource /users
USERS_ID=$(aws apigateway create-resource \
  --rest-api-id $API_ID \
  --parent-id $ROOT_ID \
  --path-part "users" \
  --query 'id' --output text)

# Membuat GET method pada /users
aws apigateway put-method \
  --rest-api-id $API_ID \
  --resource-id $USERS_ID \
  --http-method GET \
  --authorization-type NONE

# Membuat POST method pada /users
aws apigateway put-method \
  --rest-api-id $API_ID \
  --resource-id $USERS_ID \
  --http-method POST \
  --authorization-type NONE

Lambda Integration

Bash
# Integrasi GET /users dengan Lambda function
aws apigateway put-integration \
  --rest-api-id $API_ID \
  --resource-id $USERS_ID \
  --http-method GET \
  --type AWS_PROXY \
  --integration-http-method POST \
  --uri "arn:aws:apigateway:ap-southeast-1:lambda:path/2015-03-31/functions/arn:aws:lambda:ap-southeast-1:123456789:function:getUsers/invocations"

# Memberikan permission agar API Gateway bisa invoke Lambda
aws lambda add-permission \
  --function-name getUsers \
  --statement-id apigateway-invoke \
  --action lambda:InvokeFunction \
  --principal apigateway.amazonaws.com \
  --source-arn "arn:aws:execute-api:ap-southeast-1:123456789:${API_ID}/*/GET/users"

Mendeploy API

Bash
# Membuat deployment baru
aws apigateway create-deployment \
  --rest-api-id $API_ID \
  --stage-name prod \
  --stage-description "Production stage" \
  --description "Initial deployment"

# Endpoint sekarang tersedia di:
# https://${API_ID}.execute-api.ap-southeast-1.amazonaws.com/prod/users

# Menggunakan AWS SAM (lebih mudah untuk serverless)
# template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31

Globals:
  Api:
    Cors:
      AllowMethods: "'GET,POST,PUT,DELETE,OPTIONS'"
      AllowHeaders: "'Content-Type,Authorization'"
      AllowOrigin: "'*'"

Resources:
  MyApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: prod
      Auth:
        DefaultAuthorizer: CognitoAuthorizer
        Authorizers:
          CognitoAuthorizer:
            UserPoolArn: !GetAtt UserPool.Arn

  GetUsersFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: src/
      Handler: users.getUsers
      Runtime: nodejs18.x
      Events:
        GetUsers:
          Type: Api
          Properties:
            RestApiId: !Ref MyApi
            Path: /users
            Method: get

4. Stages & Deployments

Stage di API Gateway adalah snapshot dari API Anda pada titik waktu tertentu. Setiap stage memiliki URL endpoint sendiri dan konfigurasi terpisah untuk throttling, caching, logging, dan environment variables.

Common Stage Patterns

Stage Penggunaan
devDevelopment β€” aktif, bisa diubah kapan saja
stagingPre-production β€” mirror production untuk testing
prodProduction β€” stabil, dilindungi oleh throttle dan auth
v1, v2Versioning β€” bisa menjalankan versi berbeda secara paralel

Stage Variables

Stage variables memungkinkan Anda menggunakan nilai yang berbeda per stage β€” berguna untuk mengarahkan ke backend yang berbeda (misalnya database dev vs production).

Bash
# Set stage variables
aws apigateway create-deployment \
  --rest-api-id $API_ID \
  --stage-name dev

aws apigateway update-stage \
  --rest-api-id $API_ID \
  --stage-name dev \
  --patch-operations \
    op=replace,path=/variables/backendUrl,value="https://dev-api.example.com" \
    op=replace,path=/variables/lambdaAlias,value="dev"

# Production stage dengan stage variables berbeda
aws apigateway create-deployment \
  --rest-api-id $API_ID \
  --stage-name prod

aws apigateway update-stage \
  --rest-api-id $API_ID \
  --stage-name prod \
  --patch-operations \
    op=replace,path=/variables/backendUrl,value="https://prod-api.example.com" \
    op=replace,path=/variables/lambdaAlias,value="prod"

# Menggunakan stage variables di integration URI:
# arn:aws:apigateway:region:lambda:path/2015-03-31/functions/
#   arn:aws:lambda:region:account:function:${stageVariables.lambdaAlias}/invocations

Canary Deployment

Canary deployment memungkinkan Anda mengarahkan sebagian kecil traffic ke versi baru API β€” berguna untuk testing di production sebelum full rollout.

Bash
# Membuat canary release β€” 10% traffic ke versi baru
aws apigateway update-stage \
  --rest-api-id $API_ID \
  --stage-name prod \
  --patch-operations \
    op=replace,path=/canarySettings/percentTraffic,value="10" \
    op=replace,path=/canarySettings/deploymentId,value="$NEW_DEPLOYMENT_ID"

# Monitor canary performance via CloudWatch
# Jika sukses, tingkatkan persentase secara bertahap

# Promote canary ke 100% (menjadi deployment utama)
aws apigateway update-stage \
  --rest-api-id $API_ID \
  --stage-name prod \
  --patch-operations \
    op=replace,path=/deploymentId,value="$NEW_DEPLOYMENT_ID"

5. Throttling & Rate Limiting

API Gateway menyediakan throttling built-in untuk melindungi backend dari traffic berlebihan. Throttling bekerja di beberapa level: account-wide, per stage, dan per method.

Throttling Levels

Level Default Penjelasan
Account-wide10,000 req/detikLimit untuk semua API di satu region
Per Stage10,000 req/detikLimit per stage (dev, prod, dll)
Per MethodMengikuti stageLimit per HTTP method per resource
Usage PlansCustom per clientLimit per API key / client

Konfigurasi Throttling

Bash
# Set stage-level throttle
aws apigateway update-stage \
  --rest-api-id $API_ID \
  --stage-name prod \
  --patch-operations \
    op=replace,path=/throttling/rateLimit,value="5000" \
    op=replace,path=/throttling/burstLimit,value="2000"

# Set method-level throttle (lebih ketat untuk POST)
aws apigateway update-stage \
  --rest-api-id $API_ID \
  --stage-name prod \
  --patch-operations \
    op=replace,path=/~1users/POST/throttling/rateLimit,value="100" \
    op=replace,path=/~1users/POST/throttling/burstLimit,value="200"

Usage Plans & API Keys

Usage plans memungkinkan Anda memberikan limit yang berbeda ke client yang berbeda. Setiap client mendapatkan API key yang terkait dengan usage plan tertentu.

Bash
# Membuat usage plan
PLAN_ID=$(aws apigateway create-usage-plan \
  --name "Basic Plan" \
  --description "Basic tier - 1000 req/day" \
  --throttle rateLimit=10,burstLimit=20 \
  --quota limit=1000,period=DAY \
  --api-stages apiId=$API_ID,stage=prod \
  --query 'id' --output text)

# Membuat API key
KEY_ID=$(aws apigateway create-api-key \
  --name "Client App Key" \
  --enabled \
  --query 'id' --output text)

# Mengaitkan API key dengan usage plan
aws apigateway create-usage-plan-key \
  --usage-plan-id $PLAN_ID \
  --key-id $KEY_ID \
  --key-type API_KEY

# Client menggunakan API key di header:
# x-api-key: YOUR_API_KEY_VALUE

6. Authorization & Authentication

API Gateway mendukung beberapa metode authentication dan authorization. Memilih metode yang tepat sangat penting untuk keamanan API Anda.

Jenis Authorization

Tipe Penjelasan Use Case
IAM AuthGunakan AWS IAM policies untuk authorize requestInternal AWS services, cross-account
Cognito User PoolsJWT token dari Cognito User PoolUser-facing apps (mobile, web)
Lambda AuthorizerCustom Lambda function yang validate tokenCustom auth logic, 3rd party JWT
JWT AuthorizerValidate JWT dari OIDC/IdP (HTTP API only)Auth0, Okta, custom IdP

Cognito Authorizer

Bash
# Membuat Cognito User Pool
USER_POOL_ID=$(aws cognito-idp create-user-pool \
  --pool-name "MyAppUsers" \
  --policies 'PasswordPolicy={MinimumLength=8,RequireUppercase=true,RequireNumbers=true}' \
  --auto-verified-attributes email \
  --query 'UserPool.Id' --output text)

# Membuat Cognito Authorizer di API Gateway
aws apigateway update-authorizer \
  --rest-api-id $API_ID \
  --authorizer-id $AUTH_ID \
  --patch-operations \
    op=replace,path=/identitySource,value="method.request.header.Authorization" \
    op=replace,path=/type,value="COGNITO_USER_POOLS" \
    op=replace,path=/providerARNs,value="[\"arn:aws:cognito-idp:ap-southeast-1:123456789:userpool/$USER_POOL_ID\"]"

# Set authorizer pada method
aws apigateway update-method \
  --rest-api-id $API_ID \
  --resource-id $USERS_ID \
  --http-method GET \
  --patch-operations \
    op=replace,path=/authorizationType,value="COGNITO_USER_POOLS" \
    op=replace,path=/authorizerId,value="$AUTH_ID"

Lambda Authorizer

JavaScript
// Lambda Authorizer function
exports.handler = async (event) => {
  const token = event.authorizationToken; // "Bearer xxxxx"
  
  try {
    // Validasi JWT token
    const decoded = jwt.verify(
      token.replace('Bearer ', ''),
      process.env.JWT_SECRET
    );
    
    // Return IAM policy yang mengizinkan akses
    return generatePolicy(decoded.sub, 'Allow', event.methodArn);
  } catch (err) {
    // Token tidak valid β€” tolak akses
    return generatePolicy('user', 'Deny', event.methodArn);
  }
};

function generatePolicy(principalId, effect, resource) {
  return {
    principalId,
    policyDocument: {
      Version: '2012-10-17',
      Statement: [{
        Action: 'execute-api:Invoke',
        Effect: effect,
        Resource: resource
      }]
    },
    // Context bisa diakses di Lambda backend
    context: {
      userId: principalId,
      role: 'user'
    }
  };
}

7. Request/Response Mapping

API Gateway mendukung transformasi data request dan response menggunakan VTL (Velocity Template Language) mapping templates. Ini berguna untuk mengubah format data antara client dan backend.

Request Mapping Template

VTL
## Contoh VTL Request Mapping Template
## Mengubah query parameter menjadi Lambda event yang rapi

#set($inputRoot = $input.path('$'))
{
  "userId": "$input.params('user-id')",
  "queryString": "$input.params('q')",
  "requestId": "$context.requestId",
  "sourceIp": "$context.identity.sourceIp",
  "timestamp": "$context.requestTime",
  "headers": {
    #foreach($header in $input.params().header.keySet())
    "$header": "$input.params().header.get($header)"#if($foreach.hasNext),#end
    #end
  }
}

Response Mapping Template

VTL
## Response mapping β€” wrap Lambda response ke format API standar
#set($inputRoot = $input.path('$'))
{
  "status": "success",
  "data": $input.json('$'),
  "metadata": {
    "requestId": "$context.requestId",
    "timestamp": "$context.requestTime",
    "latency": "$context.integrationLatency"
  }
}

## Error response mapping
#if($input.path('$.errorMessage').contains("not found"))
#set($context.responseOverride.status = 404)
{
  "status": "error",
  "code": "RESOURCE_NOT_FOUND",
  "message": "$input.path('$.errorMessage')"
}
#else
#set($context.responseOverride.status = 500)
{
  "status": "error",
  "code": "INTERNAL_ERROR",
  "message": "An unexpected error occurred"
}
#end

8. Custom Domain Names

Secara default, API Gateway menggunakan URL yang tidak mudah diingat: https://abc123xyz.execute-api.ap-southeast-1.amazonaws.com/prod. Anda bisa menggunakan custom domain name untuk URL yang lebih profesional.

Setup Custom Domain

Bash
# 1. Buat/minta SSL certificate di ACM (harus di us-east-1 untuk edge-optimized)
aws acm request-certificate \
  --domain-name "api.example.com" \
  --validation-method DNS \
  --region us-east-1

# 2. Buat custom domain name di API Gateway
aws apigateway create-domain-name \
  --domain-name "api.example.com" \
  --regional-certificate-arn "arn:aws:acm:ap-southeast-1:123456789:certificate/xxx" \
  --endpoint-configuration types=REGIONAL \
  --security-policy TLS_1_2

# 3. Buat base path mapping
aws apigateway create-base-path-mapping \
  --domain-name "api.example.com" \
  --base-path "v1" \
  --rest-api-id $API_ID \
  --stage prod

# 4. Buat DNS record di Route 53
aws route53 change-resource-record-sets \
  --hosted-zone-id Z123456789 \
  --change-batch '{
    "Changes": [{
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "api.example.com",
        "Type": "A",
        "AliasTarget": {
          "HostedZoneId": "Z2FDTNDATAQYW2",
          "DNSName": "d-xxx.execute-api.ap-southeast-1.amazonaws.com",
          "EvaluateTargetHealth": false
        }
      }
    }]
  }'

9. Caching

REST API di API Gateway mendukung built-in caching yang menyimpan response untuk periode waktu tertentu. Ini mengurangi beban backend dan mempercepat response time untuk request yang berulang.

Konfigurasi Cache

Bash
# Enable cache pada stage
aws apigateway update-stage \
  --rest-api-id $API_ID \
  --stage-name prod \
  --patch-operations \
    op=replace,path=/cacheClusterEnabled,value=true \
    op=replace,path=/cacheClusterSize,value="0.5" \
    op=replace,path=/~1users/GET/caching/enabled,value=true \
    op=replace,path=/~1users/GET/caching/ttlInSeconds,value="300"

# Cache sizes: 0.5, 1.6, 6.1, 13.5, 28.4, 58.2, 118, 237 GB

# Invalidate cache (setelah data berubah)
aws apigateway flush-stage-cache \
  --rest-api-id $API_ID \
  --stage-name prod
⚠️ Peringatan

Cache menghasilkan biaya tambahan. Gunakan cache hanya untuk endpoint yang sering diakses dengan data yang jarang berubah (seperti konfigurasi, daftar produk, dll). Jangan cache data user-specific tanpa cache key yang tepat.

10. Best Practices

API Design

Security

Performance

Monitoring

Bash
# Enable access logging
aws apigateway update-stage \
  --rest-api-id $API_ID \
  --stage-name prod \
  --patch-operations \
    op=replace,path=/accessLogSettings/destinationArn,value="arn:aws:logs:ap-southeast-1:123456789:log-group:api-gateway-logs" \
    op=replace,path=/methodSettings/*/*/loggingLevel,value="INFO" \
    op=replace,path=/methodSettings/*/*/metricsEnabled,value=true \
    op=replace,path=/methodSettings/*/*/dataTraceEnabled,value=true"

# CloudWatch metrics tersedia:
# - 4XXError: Client errors (bad request, unauthorized, dll)
# - 5XXError: Server errors (backend failures)
# - Latency: Total response time (gateway + backend)
# - IntegrationLatency: Waktu backend processing
# - Count: Jumlah total request
# - CacheHitCount / CacheMissCount

πŸ“ Quiz Pemahaman

Pertanyaan 1: Berapa harga per juta request untuk HTTP API dibanding REST API?

a) HTTP API $3.50, REST API $1.00
b) HTTP API $1.00, REST API $3.50
c) Sama-sama $1.00
d) Sama-sama $3.50

Pertanyaan 2: Apa fungsi utama Lambda Authorizer?

a) Meng-cache response API
b) Mengubah format request/response
c) Memvalidasi token dan menghasilkan IAM policy untuk otorisasi
d) Mengelola deployment stages

Pertanyaan 3: Apa yang terjadi ketika throttling limit tercapai?

a) Request diproses lebih lambat
b) Request di-queue dan diproses nanti
c) Client menerima HTTP 429 Too Many Requests
d) API Gateway restart otomatis

Pertanyaan 4: Fitur apa yang HANYA tersedia di REST API dan TIDAK di HTTP API?

a) Lambda integration
b) Caching dan Request Validation
c) JWT Authorizer
d) CORS support

Pertanyaan 5: Apa tujuan utama canary deployment di API Gateway?

a) Mengurangi biaya API
b) Mengarahkan sebagian kecil traffic ke versi baru untuk testing di production
c) Meng-cache response API
d) Mengelola multiple API keys
πŸ” Zoom
100%
🎨 Tema