API Gateway — HTTP API
HTTP API adalah versi API Gateway yang lebih sederhana dan lebih murah dari REST API. Untuk 90% aplikasi GenAI, ini pilihan yang tepat.
Intisari
- Dua produk berbeda: HTTP API (sederhana, murah) dan REST API (fitur lebih banyak).
- Bawaan: CORS, deployment otomatis, dan otorisasi JWT/OIDC tanpa menulis kode.
- Route berbentuk
METHOD /path, diarahkan ke integrasi — biasanya Lambda proxy. - Payload proxy versi 2.0:
event["body"]berupa string, dan jalur ada dirawPath. - Untuk streaming, API Gateway meneruskan lewat integrasi proxy — tapi tetap tunduk pada batas waktunya.
HTTP API atau REST API?
| HTTP API | REST API | |
|---|---|---|
| Harga | Jauh lebih murah | Lebih mahal |
| Otorisasi JWT bawaan | Ya | Tidak (perlu Lambda authorizer) |
| API key & usage plan | Tidak | Ya |
| Validasi request & transformasi | Terbatas | Lengkap (VTL) |
| Cache bawaan | Tidak | Ya |
| WAF | Tidak langsung | Ya |
Mulai dari HTTP API. Pindah ke REST API hanya kalau kamu benar-benar butuh usage plan, cache bawaan, atau WAF yang menempel langsung.
Anatomi
Klien ──▶ Route "POST /tanya"
└─▶ Integrasi (Lambda proxy: tanya-bedrock)
└─▶ Stage ($default, deploy otomatis)
aws apigatewayv2 create-api \
--name tanya-api \
--protocol-type HTTP \
--target arn:aws:lambda:us-east-1:123456789012:function:tanya-bedrock
Bentuk --target di atas adalah jalan pintas: ia sekaligus membuat route $default,
integrasi proxy, dan stage $default. Untuk aplikasi nyata, definisikan route secara eksplisit
lewat IaC (Fase 2).
Bentuk event versi 2.0
def handler(event, context):
metode = event["requestContext"]["http"]["method"] # "POST"
jalur = event["rawPath"] # "/tanya"
body = json.loads(event.get("body") or "{}") # string → dict
return {
"statusCode": 200,
"headers": {"Content-Type": "application/json"},
"body": json.dumps({"jawaban": "..."}, ensure_ascii=False),
}
Tiga kesalahan yang selalu terjadi di hari pertama:
(1) lupa json.loads(event["body"]) — body selalu string;
(2) lupa json.dumps pada nilai balik — mengembalikan dict mentah menghasilkan
Internal Server Error yang tidak menjelaskan apa-apa;
(3) permintaan dengan isBase64Encoded: true (mis. unggahan biner) yang di-parse langsung tanpa
di-decode.
CORS
Kalau frontend-mu berbeda origin, aktifkan CORS di level API — jangan menambal header di kode Lambda.
API Gateway yang menjawab preflight OPTIONS, sehingga Lambda-mu tidak perlu tahu soal CORS sama sekali.
aws apigatewayv2 update-api --api-id abc123 \
--cors-configuration AllowOrigins=https://app.contoh.com,AllowMethods=POST,AllowHeaders=content-type
Otorisasi
| Jenis | Cocok untuk |
|---|---|
| JWT authorizer | Pengguna dari Cognito atau penyedia OIDC lain — tanpa kode |
| Lambda authorizer | Logika kustom: API key sendiri, cek kuota, multi-tenant |
| IAM | Pemanggil internal AWS (service ke service) |
Batas yang perlu diingat untuk aplikasi LLM
- Timeout integrasi maksimum 30 detik. Jawaban model yang panjang bisa melewatinya — ini alasan struktural untuk streaming, bukan sekadar demi pengalaman pengguna.
- Payload 10 MB. Unggahan dokumen sebaiknya lewat presigned URL S3, bukan lewat API.
- Throttling disetel per stage atau per route — pasang, supaya satu klien tidak menghabiskan kuota Bedrock-mu.
Latihan: ekspos fungsi tanya-bedrock lewat HTTP API, panggil dengan curl,
lalu sengaja kirim JSON tanpa field pertanyaan dan pastikan yang kembali adalah 400 buatanmu —
bukan 502 dari Lambda yang error. Terakhir, pasang throttle 5 permintaan/detik pada stage-nya.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.