Episode ini membedah arsitektur chi dari dalam: chi.NewRouter yang mengembalikan http.Handler, radix tree untuk mencocokkan pola, serta chi.RouteContext yang membawa params dan middleware stack lewat context Go. Kalian juga mengenal komponen utama router dan package middleware bawaan.

Episode 1 menjelaskan mengapa chi ada. Episode 2 membuka kap mesin: bagaimana chi bekerja di balik layar. Memahami arsitektur internal ini penting, karena banyak kesalahan penggunaan chi — misalnya kehilangan params atau middleware yang tidak berjalan — berakar pada kurang pahamnya konsep chi.RouteContext dan alur context.
Target episode ini sederhana: setelah selesai, kalian bisa menjelaskan alur sebuah request dari masuk sampai handler tereksekusi, termasuk dari mana params diambil dan mengapa urutan middleware penting.
chi.NewRouter() mengembalikan nilai bertipe chi.Router — sebuah interface yang implementasinya juga merupakan http.Handler. Itulah sebabnya router chi bisa langsung diserahkan ke http.ListenAndServe tanpa adaptor:
package main
import (
"net/http"
"github.com/go-chi/chi/v5"
)
func main() {
r := chi.NewRouter()
r.Get("/", func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("halo dari chi"))
})
http.ListenAndServe(":8080", r)
}Perhatikan tidak ada magic di sini. http.ListenAndServe(":8080", r) menerima router karena router mengimplementasikan ServeHTTP — persis seperti handler biasa.
Saat request datang, method ServeHTTP pada router dijalankan. Router membaca method dan path, lalu mencocokkan dengan pola yang sudah didaftarkan. Proses pencocokan inilah yang dioptimalkan lewat struktur khusus bernama radix tree.
Router internal chi menyusun seluruh pola rute dalam radix tree — sebuah pohon di mana setiap level merepresentasikan segmen path. Menemukan handler untuk /users/42 cukup dengan menelusuri node users lalu node {id}, tanpa harus membandingkan satu per satu seluruh pola yang terdaftar.
Keuntungan radix tree:
Setiap node yang menyimpan pola param (misalnya {id}) mencatat nama dan nilai saat request dicocokkan. Nilai-nilai ini disimpan di dalam route context yang akan kita bahas berikutnya.
rctx := chi.RouteContext(req.Context())
param := rctx.URLParam("id")chi.RouteContext(req.Context()) mengambil struktur konteks rute dari context request, lalu rctx.URLParam("id") membaca nilai param yang dicocokkan. Ini jalur yang dipakai chi.URLParam di episode 4.
Sejak Go 1.7, package context menjadi bagian standard library dan http.Request membawa context. chi memanfaatkannya dengan menyisipkan route context ke dalam context request. Dengan begitu, params dan middleware stack berpindah dari router ke handler tanpa variabel global.
Komponen penting dalam route context:
Saat request lewat, middleware yang terdaftar dijalankan berurutan seperti onion. Setiap middleware menerima http.Handler dan mengembalikan http.Handler baru. Route context menyimpan sisa middleware yang belum dipanggil sehingga subrouter dan With bisa menambahkan lapisan baru secara dinamis.
chi.NewRouter() — pengelola pola rute dan handler.chi.URLParam).r.Middlewares().middleware.Chain — merangkai middleware eksplisit menjadi satu handler.r.Mount — memasang sub-app sebagai handler pada prefix path.Seluruh komponen itu bekerja di atas satu basis: net/http.
chi menyertakan middleware package berisi utilitas siap pakai. Beberapa yang akan sering kalian pakai:
middleware.RequestID dan middleware.RealIP untuk metadata request.middleware.Logger untuk logging sederhana.middleware.Recoverer untuk menangkap panic.middleware.Timeout dan middleware.Throttle untuk pengendalian.middleware.Compress, middleware.BasicAuth, dan middleware.RedirectSlashes.Kita akan mengeksplorasi semuanya secara mendalam mulai episode 6. Untuk sekarang, cukup pahami bahwa package ini hanyalah fungsi func(http.Handler) http.Handler biasa.
go doc github.com/go-chi/chi/v5/middlewarego doc github.com/go-chi/chi/v5/middleware menampilkan daftar lengkap middleware yang tersedia beserta tanda tangannya.
Inti yang harus dibawa pulang:
chi.NewRouter() mengembalikan chi.Router yang juga http.Handler.chi.RouteContext dibawa lewat context Go dan menyimpan params serta middleware stack.chi.URLParam atau rctx.URLParam.func(http.Handler) http.Handler.net/http.Di episode 3 selanjutnya kita akan menulis kode pertama yang benar-benar jalan: setup dan hello world — dari install chi v5, chi.NewRouter(), handler pertama, sampai prinsip chi adalah net/http yang bisa kalian raba langsung lewat curl.