Kodeloka
  1. Kodeloka
  2. Kelas Kong API Gateway
  3. Materi

3 · Plugin · Modul 5 dari 12

Anatomi Plugin & Urutan Eksekusi

Bagaimana plugin dijalankan, empat tingkat cakupan yang menentukan mana yang menang, dan kenapa urutannya sering menjadi sumber bug.

🔄 Fase Pemrosesan

Permintaan masuk
   │
   ├─ certificate     → penanganan TLS, mTLS
   ├─ rewrite         → sebelum routing dikenali
   ├─ access          → SETELAH route dikenali (mayoritas plugin di sini:
   │                     auth, rate limit, ACL, transformasi request)
   │
   ├──────────> diteruskan ke upstream
   │
   ├─ header_filter   → mengubah header respons
   ├─ body_filter     → mengubah isi respons
   └─ log             → setelah respons dikirim ke klien
💡 Fase log tidak menambah latensi

Plugin logging berjalan setelah respons sudah dikirim ke klien, sehingga tidak memperlambat permintaan. Inilah sebabnya mengirim log ke sistem eksternal relatif aman — berbeda dengan plugin pada fase access yang setiap milidetiknya langsung terasa oleh pengguna.

🎚️ Empat Tingkat Cakupan

plugins:
  # 1. GLOBAL — berlaku untuk semua
  - name: correlation-id
    config:
      header_name: X-Request-Id
      generator: uuid

  # 2. Per SERVICE
  - name: rate-limiting
    service: layanan-pesanan
    config: { minute: 100 }

  # 3. Per ROUTE — lebih spesifik
  - name: rate-limiting
    route: rute-pesanan-publik
    config: { minute: 20 }

  # 4. Per CONSUMER — paling spesifik
  - name: rate-limiting
    consumer: mitra-premium
    config: { minute: 10000 }
⚠️ Plugin yang sama TIDAK menumpuk

Bila rate-limiting dipasang di tingkat global, Service, dan Route sekaligus, hanya satu yang berlaku — yang paling spesifik. Batasnya tidak dijumlahkan atau digabungkan.

Urutan spesifisitas dari yang paling menang: Consumer + Route → Consumer + Service → Consumer → Route → Service → Global. Salah paham soal ini menghasilkan konfigurasi di mana orang mengira sudah memasang batas ketat, padahal yang berlaku batas longgar dari tingkat lain.

🔢 Urutan Antar Plugin Berbeda

Plugin yang berbeda dijalankan berdasarkan nilai priority bawaannya — semakin besar semakin dulu. Urutan penulisan di berkas tidak berpengaruh.

PluginPriority (kira-kira)Jalan pada
pre-functionSangat tinggiaccess
corsTinggiaccess
jwt / key-auth / oauth2Menengah-tinggiaccess
aclSetelah authaccess
rate-limitingSetelah aclaccess
request-transformerMenengahaccess
proxy-cacheRendahaccess
file-log / http-logSangat rendahlog
💡 Urutan ini masuk akal secara logis

Autentikasi berjalan sebelum ACL karena ACL perlu tahu siapa penggunanya. Rate limiting berjalan setelah autentikasi agar kuota bisa dihitung per konsumen, bukan sekadar per alamat IP. Membalik urutan ini akan merusak model kuota Anda.

🧩 Plugin yang Paling Sering Dipakai

Autentikasi : key-auth, jwt, basic-auth, oauth2, ldap-auth
Keamanan    : acl, ip-restriction, bot-detection, cors
Lalu lintas : rate-limiting, request-size-limiting, proxy-cache,
              request-termination
Transformasi: request-transformer, response-transformer,
              correlation-id
Observability: prometheus, http-log, file-log, opentelemetry, zipkin
Serverless  : pre-function, post-function (Lua kustom)
📌 correlation-id sebaiknya global sejak hari pertama

Plugin ini menyuntikkan ID unik ke setiap permintaan dan meneruskannya ke upstream. Ketika ada masalah, satu ID itu memungkinkan Anda melacak satu permintaan melintasi gateway dan seluruh layanan di belakangnya. Biayanya nyaris nol, manfaatnya besar saat insiden.

🐛 Menelusuri Plugin yang Tidak Bekerja

# Semua plugin yang aktif
curl -s http://localhost:8001/plugins | jq '.data[] |
  {name, enabled, service: .service.id, route: .route.id, consumer: .consumer.id}'

# Plugin pada satu route tertentu
curl -s http://localhost:8001/routes/rute-pesanan/plugins | jq

# Menonaktifkan sementara tanpa menghapus
curl -X PATCH http://localhost:8001/plugins/<id> --data "enabled=false"

Bila sebuah plugin tampak tidak berpengaruh, penyebab yang paling sering: ada instance plugin yang sama di tingkat lebih spesifik yang menimpanya, atau plugin dipasang di Service padahal Route yang menangani permintaan tersebut sudah punya konfigurasi sendiri.