Episode ini mengupas middleware sebagai fungsi yang membungkus handler: cara menulisnya, mendaftarkannya dengan r.Use, dan merangkainya secara eksplisit dengan middleware.Chain. Kalian juga menjelajahi middleware bawaan chi seperti RequestID, Logger, Recoverer, Compress, dan BasicAuth, termasuk catatan perbaikan open redirect pada RedirectSlashes.

Middleware adalah alasan banyak orang memilih chi. Dengan satu pola sederhana — fungsi yang menerima dan mengembalikan http.Handler — kalian bisa menambahkan autentikasi, logging, recovery, kompresi, dan batasan beban tanpa mengubah satu baris handler pun.
Episode 6 menjelaskan cara middleware bekerja, cara menulisnya, dan middleware bawaan apa saja yang siap dipakai. Di akhir episode, kalian bisa membangun rantai middleware yang terstruktur dan tahu persis urutan eksekusinya.
Middleware adalah fungsi bertanda func(http.Handler) http.Handler. Saat request masuk, middleware dipanggil lebih dulu, lalu menyerahkan kontrol ke handler berikutnya — membentuk lapisan seperti onion.
func tambahHeader(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("X-Powered-By", "chi")
next.ServeHTTP(w, req)
})
}next.ServeHTTP(w, req) adalah titik serah-terima: sebelum baris itu kalian bisa memproses request masuk, sesudahnya kalian bisa memproses respons keluar. Middleware ini menambahkan header di setiap respons.
func timer(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
start := time.Now()
next.ServeHTTP(w, req)
durasi := time.Since(start)
w.Header().Set("X-Durasi", durasi.String())
})
}Perhatikan kode sebelum next.ServeHTTP berjalan saat request masuk; kode sesudahnya berjalan setelah handler selesai. Ini pola yang dipakai logging dan metrics.
r := chi.NewRouter()
r.Use(middleware.RequestID)
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Use(tambahHeader)
r.Get("/", homeHandler)r.Use(middleware.Recoverer) mendaftarkan middleware yang dijalankan untuk semua route di router ini — urutan pendaftaran adalah urutan eksekusi: RequestID, Logger, Recoverer, lalu tambahHeader.
Untuk menerapkan middleware hanya pada satu route atau grup, pakai r.With:
r.With(middleware.BasicAuth("app",
map[string]string{"admin": "s3cret"})).
Get("/admin", adminHandler)r.With(middleware.BasicAuth(...)).Get("/admin", handler) membuat router baru sementara dengan middleware tambahan, tanpa memengaruhi route lain.
middleware.Chain merangkai middleware secara eksplisit menjadi satu http.Handler:
final := middleware.Chain(
middleware.RequestID,
middleware.Logger,
middleware.Recoverer,
)(finalHandler)
r.Mount("/v1", final)middleware.Chain(...)(finalHandler) mengembalikan handler baru yang menjalankan RequestID, Logger, dan Recoverer sebelum finalHandler. Berguna ketika kalian ingin membangun handler yang berdiri sendiri di luar router.
Middleware pertama di Chain adalah lapisan terluar: ia yang berjalan paling awal. Jadi tempatkan RequestID dan Logger paling atas, Recoverer di dalamnya agar panic tetap tertangkap setelah logging berjalan.
chi menyediakan utilitas siap pakai:
middleware.RequestID — menambahkan request ID dan menyimpan nilainya di context.middleware.RealIP — mengambil alamat IP asli dari header proxy.middleware.Logger — logging request sederhana.middleware.Recoverer — menangkap panic dan mengembalikan status 500.middleware.Compress — kompresi gzip/brotli untuk respons.middleware.Timeout — batas waktu eksekusi handler.middleware.Throttle — membatasi jumlah request bersamaan.middleware.BasicAuth — autentikasi basic header.middleware.RedirectSlashes — menormalisasi trailing slash.go doc github.com/go-chi/chi/v5/middlewarego doc github.com/go-chi/chi/v5/middleware menampilkan dokumentasi lengkap semua middleware bawaan beserta contohnya.
Pada awal 2026, ditemukan celah keamanan yang melibatkan RedirectSlashes: dalam kondisi tertentu, redirect yang dihasilkan bisa menjadi open redirect — mengarahkan pengguna ke domain lain. Perbaikan dirilis sebagai advisory GO-2026-4316.
Yang perlu kalian lakukan:
go get github.com/go-chi/chi/v5@latest
go mod tidygo get github.com/go-chi/chi/v5@latest menarik versi yang sudah memuat perbaikan. Selalu pastikan memakai rilis yang terbaru — keamanan aplikasi kalian mengikuti keamanan dependency.
next.ServeHTTP.Middleware yang baik adalah middleware yang bisa dipindahkan antar project tanpa perubahan.
Inti yang harus dibawa pulang:
func(http.Handler) http.Handler.r.Use menerapkan ke seluruh router; r.With inline per route.middleware.Chain merangkai middleware menjadi satu handler.Di episode 7 selanjutnya kita akan berurusan dengan output: responses, JSON, dan static files — helper JSON, HTML dan redirect, streaming, melayani file statis dengan http.FileServer, upload file, dan custom response writer.