Belajar 9router - Route Extensions & Custom Actions
Episode 16 of 23

Belajar 9router - Route Extensions & Custom Actions

Episode ini melebarkan logika gateway dengan kode: custom routing hooks dan plugin-based decision logic, aksi domain-specific yang memperpanjang 9router, serta modul rute yang bisa dipakai ulang lintas project.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Pendahuluan

Episode 15 membuat gateway cepat dan hemat. Tapi sekuat apa pun, config YAML tetap punya batas: logika routing bawaan tidak selalu tahu bahwa "request dari dashboard member premium harus diutamakan di antrean" atau "jawaban untuk customer service perlu menyisipkan data pelanggan dari sistem internal". Untuk kasus seperti ini, 9router membuka pintu menuju kode.

Episode 16 memperkenalkan ekstensi: custom routing hooks yang memotong alur keputusan, plugin dengan decision logic sendiri, aksi domain-specific yang memperpanjang kemampuan gateway, dan modul rute yang bisa dipakai ulang di banyak project. Inilah saatnya gateway tidak lagi sekadar menerima — ia bisa berpikir dengan logika kalian.

Custom Routing Hooks

Hook adalah titik suntikan di sepanjang siklus hidup request. 9router mendefinisikan beberapa titik: sebelum routing (before_route), setelah rute terpilih (after_route), sebelum request dikirim ke provider (before_upstream), dan setelah respons kembali (after_response). Di titik-titik ini kalian bisa membaca konteks, mengubah metadata, atau membatalkan request.

Mendaftarkan hooks pada alur
hooks:
  - name: prioritize-premium
    event: before_route
    action: augment_metadata
  - name: enforce-business-hours
    event: before_route
    action: reject_if_closed
  - name: log-cost-category
    event: after_response
    action: emit_log

Implementasi hook berupa kode yang mengekspor fungsi dengan konteks request:

JSHook yang menambahkan metadata prioritas
export function prioritizePremium(ctx) {
  const plan = ctx.request.metadata.plan;
  if (plan === "premium") {
    ctx.request.metadata.priority = "high";
  }
  return { action: "continue", ctx };
}

Hook yang berubah-ubah sepanjang versi harus punya kebijakan versi tersendiri, sama seperti kebijakan routing di episode 10 — tanda tangani versi hook agar keputusan lama tetap bisa diaudit.

Plugin-based Decision Logic

Hook menyuntik satu titik; plugin menggantikan bagian logika yang lebih besar — termasuk pemilihan route itu sendiri. Plugin adalah paket yang bisa diinstal, berisi satu atau lebih function yang dieksekusi 9router pada fase tertentu, dan menawarkan fungsi yang tidak ada di inti.

Menginstal dan mengaktifkan plugin
9router plugin install @9router/plugin-latency-router
9router plugin enable latency-router
JSPlugin decision logic untuk pilih model
export function decideModel(request) {
  const maxLatency = request.metadata.sla_latency_ms;
  if (maxLatency && maxLatency < 800) {
    return { model: "gpt-4o-mini", reason: "sla_latency" };
  }
  return { model: "gpt-4o", reason: "default" };
}

Plugin latency-router di atas memilih model berdasarkan SLA latensi yang diminta — logika yang tidak masuk akal dihardcode ke config murni. Setiap plugin dijalankan dalam sandbox: akses dibatasi, dan jika plugin error, gateway kembali ke decision logic bawaan alih-alih gagal total.

Menyetel plugin di konfigurasi
plugins:
  latency-router:
    version: "1.4.0"
    sandbox: true
    fallback: builtin
    timeout: 10ms

Daftar plugin yang aktif dan versinya bisa dicek dengan 9router plugin list.

Aksi Domain-Specific

Selain mengubah keputusan, kalian bisa menambahkan aksi baru yang spesifik untuk domain kalian — hal yang tidak akan pernah ada di 9router bawaan. Contohnya aksi yang mengisi data pelanggan dari CRM sebelum prompt dikirim, atau aksi yang menyisipkan hasil query SQL ke dalam konteks model.

Mendefinisikan aksi domain sendiri
actions:
  - name: inject-customer-context
    event: before_upstream
    inputs:
      customer_id: metadata.customer_id
    output_field: context.customer_summary

Implementasi aksinya adalah kode biasa yang dipanggil 9router dengan argumen terstruktur:

Aksi yang memuat data pelanggan dari API internal
export async function loadCustomerSummary({ customerId }) {
  const res = await fetch(`https://crm.internal/customers/${customerId}`);
  if (!res.ok) throw new Error("customer load failed");
  return { summary: await res.text(), source: "crm" };
}

Hasilnya disuntikkan ke context.customer_summary dan tersedia untuk template prompt route tersebut. Perhatikan keamanannya: aksi memanggil host internal, jadi pastikan host di-allowlist seperti yang dibahas di episode 11, dan semua invocation tercatat di audit tool_invocation dari episode 14.

Warning

Aksi yang memanggil layanan eksternal adalah jalur data baru. Terapkan timeout, retry terbatas, dan fallback: jika CRM sedang mati, lebih baik melewati penyuntikan konteks daripada memblokir seluruh request.

Modul Rute yang Bisa Dipakai Ulang

Banyak workflow berulang di semua project: customer support dengan guard, terjemahan dengan format ketat, atau ekstraksi terstruktur dengan schema. Route modules membungkus satu workflow lengkap — rute, guardrail, cache, aksi, dan kebijakan — menjadi satu paket yang bisa di-import ke project mana pun.

Mendefinisikan modul rute yang bisa dipakai ulang
route_modules:
  - name: support-handoff
    version: "2.1.0"
    routes:
      - support-triage
    includes:
      - guardrails: [moderation-in, pii-scrub]
      - cache: support-cache
      - actions: [inject-customer-context]
Memakai modul di project lain
imports:
  - module: support-handoff
    version: "2.1.0"
    overrides:
      support-triage:
        model: gpt-4o-mini

Modul memberi konsistensi: tim lain tidak perlu menebak-nebak konfigurasi guard yang benar. overrides memungkinkan penyesuaian lokal tanpa mengubah kode modul. Dengan membungkus rute, guard, aksi, dan kebijakan jadi satu unit, kalian membangun perangkat standar perusahaan — persis yang nantinya menjadi pijakan saat mendokumentasikan standar routing di episode 21.

Penutup

Episode 16 mengubah 9router dari config murni menjadi platform yang bisa diprogram: custom routing hooks menyuntik logika di titik-titik penting alur request, plugin menggantikan decision logic besar dengan kode bersandbox, aksi domain-specific memperpanjang kemampuan gateway dengan logika bisnis kalian, dan modul rute membungkus workflow lengkap agar bisa dipakai ulang lintas project.

Inti yang harus dibawa pulang:

  • Hook menyuntik satu titik alur; plugin menggantikan keseluruhan logika; pilih sesuai skala perubahan.
  • Jalankan plugin dan aksi dalam sandbox dengan timeout dan fallback ke logika bawaan.
  • Aksi domain-specific adalah jalur data baru — terapkan allowlist host, timeout, retry, dan audit.
  • Verifikasi hasil ekstensi dengan pengujian sebelum dipromosikan, dan jadikan kebiasaan.
  • Modul rute membungkus workflow lengkap agar standar yang sama berlaku di semua project.

Gateway kalian kini bisa berpikir dengan logika bisnis sendiri. Di episode 17 kita membawanya ke skala dunia: Distributed & Multi-region Routing — edge routing, pemilihan model regional, pengurangan latensi untuk user global, serta failover multi-region dan redundansi provider. Sampai jumpa di sana!

Belajar 9router - Route Extensions & Custom Actions | Belajar 9router