Serverless menggeser paradigma dari "mengelola server" ke "menulis fungsi": API Gateway + Lambda/Cloud Functions/Functions, pola event-driven, dan trade-off yang harus dipahami — terutama cold start dan timeout. Kalian membangun serverless API end-to-end dari nol hingga siap dipanggil publik.

Di episode 3 kalian sudah men-deploy function serverless pertama. Sekarang kita bangun arsitektur serverless yang utuh — bukan sekadar fungsi, melainkan sistem: API publik, event-driven processing, database, dan seluruh pola yang menjadikan serverless pilihan arsitektur, bukan sekadar teknologi.
Episode 11 membahas API Gateway + Lambda (AWS), Cloud Functions/Cloud Run + API Gateway (GCP), dan Functions + API Management (Azure). Kalian akan memahami kapan serverless adalah keputusan tepat, apa trade-off nyatanya (cold start, timeout, biaya), dan bagaimana membangun serverless API lengkap yang benar-benar berfungsi.
Serverless bukan "tidak ada server" — tetap ada server, tapi kalian tidak mengelolanya. Provider menangani provisioning, scaling, dan availability; kalian hanya mengirim kode fungsi dan membayar eksekusinya. Pola arsitektur yang paling umum:
Ada tiga pola utama:
API Gateway menyediakan endpoint HTTP publik, melakukan auth, throttling, dan SSL — kemudian memanggil fungsi. Arsitektur tipikal:
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
NotesFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: notes/
Handler: app.handler
Runtime: python3.12
Events:
CreateNote:
Type: Api
Properties:
Path: /notes
Method: POST
ListNotes:
Type: Api
Properties:
Path: /notes
Method: GETsam build
sam deploy --guidedDeploy menghasilkan endpoint publik seperti https://abcdef.execute-api.ap-southeast-1.amazonaws.com/Prod/notes. Function handler-nya:
import json
import boto3
import os
table = boto3.resource("dynamodb").Table(os.environ["TABLE_NAME"])
def handler(event, context):
method = event["httpMethod"]
path = event["path"]
if method == "POST" and path == "/notes":
body = json.loads(event["body"])
item = {"id": body["id"], "content": body["content"]}
table.put_item(Item=item)
return {"statusCode": 201, "body": json.dumps(item)}
if method == "GET" and path == "/notes":
items = table.scan()["Items"]
return {"statusCode": 200, "body": json.dumps(items)}
return {"statusCode": 404, "body": "not found"}Perhatikan: tidak ada server untuk di-provision, tidak ada framework web untuk di-urus — hanya fungsi murni yang menerima event dan mengembalikan response.
gcloud functions deploy notes-api \
--gen2 \
--runtime python312 \
--trigger-http \
--allow-unauthenticated \
--entry-point handler \
--region asia-southeast2az functionapp create --consumption-plan-location southeastasia \
--runtime python --name func-notes-uniq \
--functions-version 4
az functionapp function create --function-name notes \
--http-trigger --authlevel anonymous \
--resource-group rg-lab --name func-notes-uniqServerless bersinar ketika sistem berjalan berdasarkan peristiwa, bukan permintaan langsung. Contoh nyata: upload foto profil (dari episode 4) memicu pipeline pembuatan thumbnail.
aws lambda add-permission --function-name make-thumbnail \
--statement-id s3-invoke \
--action lambda:InvokeFunction \
--principal s3.amazonaws.com \
--source-arn arn:aws:s3:::lab-uploads
aws s3api put-bucket-notification-configuration \
--bucket lab-uploads \
--notification-configuration '{
"LambdaFunctionConfigurations": [{
"LambdaFunctionArn": "arn:aws:lambda:ap-southeast-1:123456789012:function:make-thumbnail",
"Events": ["s3:ObjectCreated:*"]
}]
}'Alur: user upload → S3 memunculkan event → Lambda membuat thumbnail → hasil ditaruh di bucket lain. Tidak ada server yang "menunggu" — sistem hidup hanya saat ada peristiwa. Ini juga menyiapkan kalian ke episode 13 (message queue & streaming) karena antrian event adalah evolusi alami dari pola ini.
Tip
Aturan praktis event-driven: fungsi harus idempotent — jika dipanggil dua kali, hasilnya sama. Event bisa dikirim ulang (retry), jadi fungsi yang berasumsi "dipanggil sekali" akan menimbulkan duplikat data. Simpan tanda pemrosesan (misal di database) untuk mencegahnya.
Serverless bukan tanpa harga. Cold start adalah kasus paling dikenal: saat fungsi idle lalu dipanggil, provider harus menyiapkan runtime baru — menambah latency ratusan ms di awal. Latency ini tidak dirasakan pada eksekusi berikutnya (warm).
| Trade-off | Dampak | Mitigasi |
|---|---|---|
| Cold start | Latency puncak tinggi di permintaan pertama | Provisioned concurrency (AWS), warmup request |
| Timeout | Fungsi dihentikan paksa (Lambda 15 menit) | Pecah jadi job pendek / step functions |
| Biaya tersembunyi | Traffic tinggi + durasi panjang bisa mahal | Hitung total cost, bandingkan VM |
| Vendor lock-in | Kode terikat event model provider | Isolasi logika bisnis dari handler |
Contoh hitungan cepat: fungsi dipanggil 10 juta kali/bulan, durasi rata-rata 200ms, memory 256MB — kira-kira puluhan dolar per bulan. Murah untuk traffic intermitten; untuk traffic stabil tinggi 24/7, VM atau container justru lebih murah. Pilih berdasarkan pola traffic, bukan tren.
Rangkai semuanya menjadi satu project:
notes-api dengan CRUD sederhana (kode di atas) + database NoSQL (DynamoDB dari episode 4).POST /notes dan GET /notes ke function.curl:curl -X POST https://abcdef.execute-api.ap-southeast-1.amazonaws.com/Prod/notes \
-H "Content-Type: application/json" \
-d '{"id":"1","content":"belajar cloud"}'
curl https://abcdef.execute-api.ap-southeast-1.amazonaws.com/Prod/notesPOST /notes, kirim event ke antrian (jembatan ke episode 13).Inti yang harus dibawa pulang:
Di episode 12 selanjutnya kita akan membahas microservices & service mesh on cloud — memecah aplikasi menjadi layanan kecil, service discovery, deployment lintas service, dan pengenalan service mesh (Istio/Linkerd) untuk observability dan security antar-service. Sampai jumpa di episode 12!