Bagaimana Cara Menerapkan Pembatasan Tingkat API yang Efektif?

Ashley Innocent

Ashley Innocent

13 March 2026

Bagaimana Cara Menerapkan Pembatasan Tingkat API yang Efektif?

Inti Masalah (TL;DR)

Terapkan pembatasan laju API menggunakan algoritma token bucket atau sliding window. Kembalikan header batas laju IETF standar (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset) dan kode status 429 Too Many Requests ketika batas terlampaui. Modern PetstoreAPI mengimplementasikan pembatasan laju dengan kuota per pengguna dan respons kesalahan yang jelas.

Pendahuluan

Seorang klien membuat 10.000 permintaan ke API Anda dalam satu menit. Basis data Anda macet. Peringatan pemantauan Anda berbunyi. Pelanggan Anda yang lain tidak dapat mengakses API. Anda diserang—atau mungkin hanya berurusan dengan klien yang mengalami bug dalam perulangan percobaan ulang.

Pembatasan laju mencegah hal ini. Ini membatasi berapa banyak permintaan yang dapat dibuat klien dalam jendela waktu. Ketika mereka melebihi batas, Anda mengembalikan 429 Too Many Requests. Klien mundur, dan API Anda tetap sehat.

Swagger Petstore lama tidak menerapkan pembatasan laju sama sekali. Modern PetstoreAPI mengimplementasikan pembatasan laju dengan header IETF standar, kuota per pengguna, dan respons kesalahan yang jelas.

💡
Jika Anda membangun atau menguji REST API, Apidog membantu Anda menguji perilaku pembatasan laju, memvalidasi header batas laju, dan memastikan API Anda menangani permintaan berlebihan dengan benar. Anda dapat mensimulasikan skenario volume tinggi dan memverifikasi respons batas laju.
tombol

Dalam panduan ini, Anda akan mempelajari algoritma pembatasan laju, header standar, dan bagaimana Modern PetstoreAPI mengimplementasikan pembatasan laju dengan benar.

Mengapa API Membutuhkan Pembatasan Laju

Pembatasan laju melindungi API Anda dari penyalahgunaan dan memastikan penggunaan yang adil.

Perlindungan Terhadap Penyalahgunaan

1. Serangan Denial-of-Service (DoS)

Penyerang membanjiri API Anda dengan permintaan untuk membuatnya tidak tersedia. Pembatasan laju membatasi dampaknya.

2. Credential stuffing

Penyerang mencoba ribuan kombinasi nama pengguna/kata sandi. Pembatasan laju memperlambat mereka.

3. Data scraping

Bot mengikis seluruh kumpulan data Anda. Pembatasan laju membuat scraping tidak praktis.

4. Kontrol biaya

Jika API Anda memanggil layanan yang mahal (model AI, API pihak ketiga), pembatasan laju mencegah biaya yang tidak terkendali.

Penggunaan yang Adil

1. Mencegah satu klien memonopoli sumber daya

Tanpa pembatasan laju, satu klien yang membuat 1000 permintaan/detik dapat menyebabkan kelangkaan bagi klien lain.

2. Performa yang dapat diprediksi

Pembatasan laju memastikan waktu respons yang konsisten untuk semua klien.

3. Akses berjenjang

Tingkat gratis: 100 permintaan/jam. Tingkat berbayar: 10.000 permintaan/jam. Pembatasan laju memberlakukan tingkat-tingkat ini.

Manfaat Operasional

1. Perencanaan kapasitas

Anda tahu beban maksimum yang akan ditangani API Anda.

2. Prediktabilitas biaya

Batas laju membatasi biaya infrastruktur.

3. Degradasi yang anggun

Di bawah beban, pembatasan laju mencegah kegagalan berantai.

Algoritma Pembatasan Laju

Algoritma yang berbeda memiliki trade-off yang berbeda.

1. Fixed Window (Jendela Tetap)

Menghitung permintaan dalam jendela waktu tetap.

Cara kerjanya:

Jendela 1 (00:00-00:59): 100 permintaan diizinkan
Jendela 2 (01:00-01:59): 100 permintaan diizinkan

Implementasi:

def is_allowed(user_id):
    current_minute = get_current_minute()
    key = f"rate_limit:{user_id}:{current_minute}"
    count = redis.incr(key)
    redis.expire(key, 60)
    return count <= 100

Kelebihan:

Kekurangan:

2. Sliding Window (Jendela Geser)

Menghitung permintaan dalam jendela waktu yang bergerak.

Cara kerjanya:

Pada 01:30, hitung permintaan dari 00:30 hingga 01:30 (60 menit terakhir).

Implementasi:

def is_allowed(user_id):
    now = time.time()
    window_start = now - 3600  # 1 jam yang lalu
    key = f"rate_limit:{user_id}"

    # Hapus permintaan lama
    redis.zremrangebyscore(key, 0, window_start)

    # Hitung permintaan dalam jendela
    count = redis.zcard(key)

    if count < 100:
        redis.zadd(key, {now: now})
        redis.expire(key, 3600)
        return True
    return False

Kelebihan:

Kekurangan:

3. Token Bucket (Keranjang Token)

Token ditambahkan ke keranjang dengan laju tetap. Setiap permintaan mengonsumsi satu token.

Cara kerjanya:

Kapasitas keranjang: 100 token
Laju pengisian ulang: 10 token/detik
Permintaan: mengonsumsi 1 token

Implementasi:

def is_allowed(user_id):
    now = time.time()
    key = f"rate_limit:{user_id}"

    # Dapatkan status saat ini
    data = redis.hgetall(key)
    tokens = float(data.get('tokens', 100))
    last_refill = float(data.get('last_refill', now))

    # Isi ulang token
    elapsed = now - last_refill
    tokens = min(100, tokens + elapsed * 10)  # 10 token/detik

    if tokens >= 1:
        tokens -= 1
        redis.hset(key, 'tokens', tokens)
        redis.hset(key, 'last_refill', now)
        redis.expire(key, 3600)
        return True
    return False

Kelebihan:

Kekurangan:

4. Leaky Bucket (Keranjang Bocor)

Permintaan ditambahkan ke antrean dan diproses dengan laju tetap.

Cara kerjanya:

Kapasitas antrean: 100 permintaan
Laju proses: 10 permintaan/detik

Kelebihan:

Kekurangan:

Algoritma Mana yang Digunakan?

Untuk sebagian besar API: Token Bucket

Ini adalah standar industri, memungkinkan burst yang wajar, dan menyediakan pembatasan laju yang mulus.

Modern PetstoreAPI menggunakan token bucket dengan kuota per pengguna.

Header Batas Laju Standar

Gunakan header standar IETF (draft-ietf-httpapi-ratelimit-headers).

Header Standar

RateLimit-Limit: Jumlah permintaan maksimum yang diizinkan dalam jendela waktu

RateLimit-Limit: 100

RateLimit-Remaining: Permintaan yang tersisa dalam jendela saat ini

RateLimit-Remaining: 45

RateLimit-Reset: Detik hingga batas laju diatur ulang

RateLimit-Reset: 3600

Contoh Respons

GET /pets
200 OK
RateLimit-Limit: 100
RateLimit-Remaining: 99
RateLimit-Reset: 3600

{
  "data": [...]
}

Header Lama (Usang)

Banyak API menggunakan header non-standar:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 99
X-RateLimit-Reset: 1710331200

Jangan gunakan ini. Prefiks X- sudah usang, dan formatnya tidak distandarisasi.

Bagaimana Modern PetstoreAPI Mengimplementasikan Pembatasan Laju

Modern PetstoreAPI mengimplementasikan pembatasan laju token bucket dengan header standar.

Batas Laju Berdasarkan Tingkat

Tingkat gratis:

Tingkat Pro:

Tingkat Enterprise:

Implementasi

Permintaan berhasil:

GET /v1/pets
200 OK
RateLimit-Limit: 100
RateLimit-Remaining: 99
RateLimit-Reset: 3540

{
  "data": [...]
}

Batas laju terlampaui:

GET /v1/pets
429 Terlalu Banyak Permintaan
Content-Type: application/problem+json
RateLimit-Limit: 100
RateLimit-Remaining: 0
RateLimit-Reset: 120
Retry-After: 120

{
  "type": "https://petstoreapi.com/errors/rate-limit-exceeded",
  "title": "Batas Laju Terlampaui",
  "status": 429,
  "detail": "Anda telah melampaui batas laju 100 permintaan per jam",
  "instance": "/v1/pets",
  "retryAfter": 120,
  "limit": 100,
  "window": "1j"
}

Per-Pengguna vs Per-IP

Per-pengguna (permintaan terautentikasi):

Batas laju berdasarkan ID pengguna atau kunci API. Lebih akurat dan adil.

user_id = get_authenticated_user()
is_allowed(user_id)

Per-IP (permintaan tidak terautentikasi):

Batas laju berdasarkan alamat IP. Kurang akurat (IP bersama, VPN) tetapi lebih baik daripada tidak sama sekali.

ip_address = request.remote_addr
is_allowed(ip_address)

Modern PetstoreAPI menggunakan pembatasan laju per-pengguna untuk permintaan terautentikasi dan per-IP untuk endpoint publik.

Format Respons Batas Laju

Ketika batas laju terlampaui, kembalikan 429 dengan format kesalahan RFC 9457.

Struktur Respons

{
  "type": "https://petstoreapi.com/errors/rate-limit-exceeded",
  "title": "Batas Laju Terlampaui",
  "status": 429,
  "detail": "Anda telah melampaui batas laju Anda. Silakan coba lagi nanti.",
  "instance": "/v1/pets",
  "retryAfter": 120,
  "limit": 100,
  "remaining": 0,
  "reset": 120,
  "window": "1j"
}
429 Terlalu Banyak Permintaan
RateLimit-Limit: 100
RateLimit-Remaining: 0
RateLimit-Reset: 120
Retry-After: 120

Retry-After: Memberi tahu klien kapan harus mencoba lagi (dalam detik).

Menguji Batas Laju dengan Apidog

Apidog membantu Anda menguji perilaku pembatasan laju.

Skenario Uji

1. Penggunaan normal:

Kirim 50 permintaan → Semua berhasil
Periksa RateLimit-Remaining berkurang

2. Melebihi batas:

Kirim 101 permintaan → yang ke-101 mengembalikan 429
Verifikasi format respons kesalahan
Periksa header Retry-After

3. Perilaku reset:

Melebihi batas → Tunggu reset → Verifikasi batas dipulihkan

4. Tingkat yang berbeda:

Uji tingkat gratis (100/jam)
Uji tingkat pro (10.000/jam)
Verifikasi batas diberlakukan dengan benar

Contoh Uji Apidog

// Uji header batas laju
pm.test("Header batas laju ada", () => {
  pm.response.to.have.header("RateLimit-Limit");
  pm.response.to.have.header("RateLimit-Remaining");
  pm.response.to.have.header("RateLimit-Reset");
});

// Uji batas laju terlampaui
pm.test("Mengembalikan 429 ketika batas terlampaui", () => {
  // Buat 101 permintaan
  for (let i = 0; i < 101; i++) {
    pm.sendRequest("GET /v1/pets");
  }
  pm.response.to.have.status(429);
});

Praktik Terbaik Pembatasan Laju

1. Gunakan header standar

Gunakan header standar IETF, bukan header X- khusus.

2. Kembalikan 429, bukan 403

429 berarti "terlalu banyak permintaan." 403 berarti "terlarang." Jangan salah mengartikan keduanya.

3. Sertakan Retry-After

Beri tahu klien kapan mereka dapat mencoba lagi.

4. Dokumentasikan batas Anda

Buat batas laju terlihat dalam dokumentasi.

5. Sediakan tingkat yang berbeda

Tingkat gratis: batas rendah. Tingkat berbayar: batas lebih tinggi.

6. Batasi laju berdasarkan pengguna, bukan IP

Batas per pengguna lebih akurat dan adil.

7. Izinkan burst

Token bucket memungkinkan burst yang wajar tanpa menghukum penggunaan normal.

8. Pantau hit batas laju

Lacak seberapa sering klien mencapai batas laju. Tingkat tinggi menunjukkan masalah.

9. Sediakan endpoint status batas laju

GET /v1/rate-limit
200 OK
{
  "limit": 100,
  "remaining": 45,
  "reset": 3540
}

10. Uji pembatasan laju

Gunakan Apidog untuk menguji perilaku batas laju sebelum deployment.

Kesimpulan

Pembatasan laju melindungi API Anda dari penyalahgunaan dan memastikan penggunaan yang adil. Gunakan algoritma token bucket dengan header standar IETF (RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset). Kembalikan 429 Too Many Requests dengan format kesalahan RFC 9457 ketika batas terlampaui.

Modern PetstoreAPI mengimplementasikan pembatasan laju dengan benar dengan kuota per pengguna, header standar, dan respons kesalahan yang jelas. Periksa dokumentasi untuk detail implementasi.

Uji pembatasan laju Anda dengan Apidog untuk memastikan bahwa itu berfungsi dengan benar di bawah beban dan menangani kasus tepi dengan tepat.

tombol

FAQ

Batas laju apa yang harus saya tetapkan?

Mulai dengan konservatif: 100 permintaan/jam untuk tingkat gratis, 10.000/jam untuk yang berbayar. Sesuaikan berdasarkan pola penggunaan dan kapasitas infrastruktur.

Haruskah saya membatasi laju berdasarkan IP atau pengguna?

Batasi laju berdasarkan pengguna (kunci API) untuk permintaan terautentikasi. Gunakan pembatasan laju berbasis IP hanya untuk endpoint publik.

Apa yang terjadi jika klien melebihi batas laju?

Kembalikan 429 Too Many Requests dengan header Retry-After. Jangan memblokir klien secara permanen—biarkan mereka mencoba lagi setelah jendela diatur ulang.

Bagaimana cara menangani batas laju untuk webhook?

Webhook adalah komunikasi server-ke-server, jadi batas laju harus lebih tinggi. Pertimbangkan batas terpisah untuk webhook vs panggilan API.

Haruskah saya membatasi laju layanan internal?

Ya, tetapi dengan batas yang jauh lebih tinggi. Pembatasan laju mencegah kegagalan berantai bahkan di sistem internal.

Bagaimana cara menguji pembatasan laju?

Gunakan Apidog untuk mengirim beberapa permintaan dan memverifikasi respons 429, header batas laju, dan perilaku reset.

Bagaimana jika API saya berada di belakang CDN?

Caching CDN mengurangi beban, tetapi Anda masih memerlukan pembatasan laju untuk cache misses dan permintaan POST/PUT/DELETE.

Bagaimana cara mengimplementasikan pembatasan laju di beberapa server?

Gunakan penyimpanan data bersama (Redis, Memcached) untuk melacak batas laju di semua server. Jangan gunakan memori lokal—itu tidak akan berfungsi dalam sistem terdistribusi.

Mengembangkan API dengan Apidog

Apidog adalah alat pengembangan API yang membantu Anda mengembangkan API dengan lebih mudah dan efisien.