Episode ini membedah arsitektur internal Gin: gin.Engine sebagai inti framework, router radix tree untuk mencocokkan path dan method, chain middleware yang berjalan berurutan, serta gin.Context yang membawa request dan response.

Sebelum menulis lebih banyak kode, penting untuk memahami apa yang terjadi di balik layar setiap kali Gin menerima sebuah request. Episode ini membedah arsitektur utama Gin: bagaimana gin.Engine menjadi pusat segalanya, bagaimana router mencocokkan URL, bagaimana middleware berantai, dan bagaimana gin.Context menjadi jembatan antara request dan response.
Pemahaman ini bukan hanya teori. Saat kalian menghadapi bug seperti routing conflict, middleware yang tidak terpanggil, atau panic di handler, pengetahuan arsitektur inilah yang akan menuntun kalian menemukan akar masalahnya.
gin.Engine adalah representasi instance framework: dia menyimpan router, daftar middleware global, konfigurasi mode (debug/release), dan konfigurasi HTTP lainnya. Setiap aplikasi Gin memiliki minimal satu Engine, dibuat lewat gin.New() atau gin.Default().
package main
import (
"github.com/gin-gonic/gin"
)
func main() {
r := gin.New()
r.Use(gin.Logger())
r.Run(":8080")
}Perbedaan gin.New(), gin.Default() dan mode debug/release akan dibahas detail di episode 3. Untuk sekarang, cukup pahami bahwa Engine adalah objek pusat yang mengatur semua rute dan middleware.
Setiap kali kalian memanggil r.GET("/users/:id", handler), Gin tidak menyimpan rute itu dalam slice biasa. Rute dimasukkan ke dalam radix tree (trie terkompresi) khusus yang mengelompokkan prefix umum. Ketika request datang, Gin menelusuri tree ini berdasarkan path dan method, sehingga pencarian selesai dalam satu lintasan.
r.GET("/users", listUsers)
r.GET("/users/:id", getUser)
r.POST("/users", createUser)Untuk rute di atas, radix tree menyatukan prefix /users menjadi satu node, dengan cabang /:id dan handler method yang berbeda. Inilah alasan mengapa rute dengan prefix sama tidak memperlambat pencarian.
/
└── users
├── (GET) -> listUsers
├── (POST) -> createUser
└── :id
└── (GET) -> getUserMiddleware adalah fungsi func(c *gin.Context) yang dijalankan berurutan. Gin memegang daftar handler untuk sebuah rute — middleware global ditambah handler final — dan mengeksekusinya seperti chain: setiap middleware bisa memanggil c.Next() untuk melanjutkan ke handler berikutnya, atau c.Abort() untuk menghentikan.
r := gin.New()
r.Use(gin.Logger()) // ke-1
r.Use(gin.Recovery()) // ke-2
r.GET("/ping", ping) // ke-3 (handler final)Alur eksekusinya: Logger mulai → Recovery mulai → ping dieksekusi → Recovery selesai → Logger selesai (biasanya menulis log setelah handler selesai). Urutan ini krusial dan akan dibahas mendalam di episode 6.
Gin memiliki beberapa tipe kunci yang akan kalian temui di seluruh series:
/api/v1.*gin.Context): membawa semua informasi request, response, dan state per-request.func(c *gin.Context).api := r.Group("/api/v1")
api.Use(requireAuth)
api.GET("/users", func(c *gin.Context) {
c.JSON(200, gin.H{"data": "daftar user"})
})
r.Run(":8080")Fungsi r.Group("/api/v1") membuat RouterGroup dengan prefix yang sama. Setiap rute di dalam grup otomatis mewarisi middleware yang dipasang di grup tersebut.
gin.Context adalah objek yang paling sering kalian pegang. Setiap request menghasilkan satu Context baru yang membawa:
c.Request (tipe *http.Request).c.Writer.c.Param("id").c.Query("page").c.Set(key, value) dan c.Get(key).func detailHandler(c *gin.Context) {
id := c.Param("id")
page := c.DefaultQuery("page", "1")
c.Set("userID", id)
c.JSON(200, gin.H{"id": id, "page": page})
}Metode c.DefaultQuery("page", "1") mengembalikan query parameter dengan nilai default jika tidak disediakan. Sementara c.Set dan c.Get menjadi sarana berbagi data antar middleware, seperti menyimpan userID setelah autentikasi.
Gin berjalan dalam mode debug secara default, yang menampilkan log rute dan lebih verbose. Untuk production, set mode release:
GIN_MODE=release go run main.gogin.SetMode(gin.ReleaseMode)
r := gin.Default()Fungsi gin.SetMode(gin.ReleaseMode) mematikan log rute saat startup dan mengurangi overhead debug. Episode 19 akan membahas optimasi ini lebih jauh.
Inti yang harus dibawa pulang:
gin.Engine adalah pusat framework: menyimpan router, middleware, dan konfigurasi.c.Next() dan bisa dihentikan via c.Abort().gin.Context membawa request, response, param, dan state per-request.Di episode 3 selanjutnya kita akan mulai menulis kode sungguhan: setup & hello world — inisialisasi proyek, install Gin, membandingkan gin.New() dengan gin.Default(), membuat rute pertama dengan GET/POST/PUT/DELETE, serta menjalankan server dengan engine.Run.