Episode ini membedah router Fiber secara menyeluruh: path parameter, wildcard, dan query parameter; constraint rute seperti :id<int> dan minLen; route chaining dan domain routing; serta group, nested group, dan mounting sub-app untuk organisasi URL yang rapi.

Router adalah jantung sebuah web framework. Episode 4 membedah routing, params, dan constraints di Fiber v3 — mulai dari pola dasar seperti /users/:id, hingga fitur baru seperti constraint bertipe dan domain routing.
Setelah episode ini, kalian bisa mendesain URL yang bersih, membatasi bentuk parameter langsung di level route, dan mengorganisasi route ke dalam group. Ini adalah keterampilan yang dipakai di setiap episode berikutnya.
Path parameter ditulis dengan prefix titik dua. Fiber menangkap nilai tersebut dan menyediakannya lewat c.Params:
app.Get("/users/:id", func(c fiber.Ctx) error {
return c.JSON(fiber.Map{"id": c.Params("id")})
})
app.Get("/files/*", func(c fiber.Ctx) error {
return c.JSON(fiber.Map{"path": c.Params("*")})
})/users/:id mencocokkan satu segmen — /users/42 — sedangkan wildcard * mencocokkan sisa path, misalnya /files/a/b/c.txt. c.Params("*") mengambil keseluruhan bagian yang cocok dengan wildcard. Di Fiber, wildcard bisa dicampur di tengah path, misalnya /users/*/posts.
Query parameter tidak mempengaruhi pencocokan route, tapi bisa dibaca lewat c.Query:
app.Get("/search", func(c fiber.Ctx) error {
q := c.Query("q", "")
page := c.Query("page", "1")
return c.JSON(fiber.Map{"q": q, "page": page})
})c.Query("q", "") mengambil nilai parameter q dengan default string kosong jika tidak ada. Untuk tipe terstruktur, kalian bisa memakai c.Bind().Query(&struct) — detailnya di episode 5.
Fiber v3 memperkenalkan route constraints — aturan yang divalidasi saat pencocokan. Jika constraint tidak terpenuhi, route dianggap tidak cocok dan request lanjut ke route berikutnya atau menuju 404:
app.Get("/users/:id<int>", func(c fiber.Ctx) error {
return c.JSON(fiber.Map{"id": c.Params("id")})
})
app.Get("/posts/:slug<minLen(5)>", func(c fiber.Ctx) error {
return c.JSON(fiber.Map{"slug": c.Params("slug")})
})
app.Get("/orders/:date<datetime(\"2006-01-02\")>", func(c fiber.Ctx) error {
return c.JSON(fiber.Map{"date": c.Params("date")})
}):id<int> hanya menerima angka, :slug<minLen(5)> menuntut minimal 5 karakter, dan :date<datetime(...)> memvalidasi format tanggal dengan layout Go. app.Get("/users/:id<int>", handler) membuat request /users/abc tidak cocok dan dikembalikan sebagai 404. Konsekuensi performanya menarik: constraint dianalisis sekali saat registrasi, bukan per request.
Jika kebutuhan constraint belum ada, Fiber menyediakan app.RegisterCustomConstraint. Interface CustomConstraint cukup diimplementasi dengan Name dan Execute:
type StatusConstraint struct{}
func (*StatusConstraint) Name() string { return "status" }
func (*StatusConstraint) Execute(param string, args ...string) bool {
switch param {
case "active", "inactive", "archived":
return true
}
return false
}
func main() {
app := fiber.New()
app.RegisterCustomConstraint(&StatusConstraint{})
app.Get("/posts/:s<status>", func(c fiber.Ctx) error {
return c.JSON(fiber.Map{"status": c.Params("s")})
})
}RegisterCustomConstraint(&StatusConstraint{}) mendaftarkan validator baru yang kemudian dipakai sebagai <status> di path. Pola ini membuat domain rule hidup di satu tempat dan reusable di banyak route.
app.RouteChain memungkinkan deklarasi beberapa method pada path yang sama dalam satu rangkaian:
app.RouteChain("/posts/:id").
Get(func(c fiber.Ctx) error {
return c.JSON(fiber.Map{"action": "get"})
}).
Post(func(c fiber.Ctx) error {
return c.JSON(fiber.Map{"action": "post"})
}).
Delete(func(c fiber.Ctx) error {
return c.JSON(fiber.Map{"action": "delete"})
})Fiber v3 mendukung route yang hanya cocok untuk hostname tertentu lewat app.Domain, dengan parameter domain yang diambil lewat fiber.DomainParam:
app.Domain("api.example.com").Get("/users", func(c fiber.Ctx) error {
return c.JSON(fiber.Map{"tenant": "public"})
})
app.Domain(":tenant.example.com").Get("/", func(c fiber.Ctx) error {
tenant := fiber.DomainParam(c, "tenant")
return c.JSON(fiber.Map{"tenant": tenant})
})app.Domain("api.example.com") membuat router terpisah yang hanya melayani hostname tersebut. Pola :tenant.example.com berguna untuk SaaS multi-tenant. Catatan penting: pastikan TrustProxy dikonfigurasi jika berada di belakang proxy, karena hostname bisa dipengaruhi header — topik kita bahas di episode 14.
app.Group membuat route dengan prefix yang sama. Group bisa di-nested dan dipakai bersama middleware:
api := app.Group("/api")
v1 := api.Group("/v1", authMiddleware)
v1.Get("/users", listUsers)
v1.Get("/users/:id", getUser)
v1.Post("/users", createUser)Route yang terdaftar menjadi /api/v1/users, dan seluruhnya melewati authMiddleware yang dipasang di group v1. app.Group("/api") mengembalikan router yang bisa diberi group lagi — pola yang dipakai untuk versioning API.
Fiber v3 juga mendukung mounting aplikasi Fiber lain sebagai sub-app, menggantikan app.Mount di v2:
api := fiber.New()
api.Get("/status", func(c fiber.Ctx) error {
return c.SendString("sub-app berjalan")
})
app := fiber.New()
app.Use("/api", api)app.Use("/api", api) memasang seluruh route dari api di bawah prefix /api. Bedanya dengan v2: prefix mount tidak di-strip, sehingga di dalam sub-app, c.Path() tetap mengembalikan path lengkap seperti /api/status.
curl -i http://localhost:3000/users/42
curl -i http://localhost:3000/users/abc
curl -i "http://localhost:3000/search?q=fiber&page=2"
curl -i http://localhost:3000/api/v1/usersRequest /users/abc seharusnya gagal constraint <int> dan mengembalikan 404, sementara /users/42 sukses. Seluruh rangkaian curl -i ... ini adalah cara cepat memverifikasi perilaku router tanpa browser.
Inti yang harus dibawa pulang:
:id; wildcard ditulis *.c.Query("key", "default").:id<int> dan :slug<minLen(5)> divalidasi saat pencocokan.RegisterCustomConstraint.RouteChain menggabungkan banyak method pada satu path; Domain membatasi hostname.Group untuk prefix bersama; app.Use("/api", subApp) untuk mounting.Di episode 5 selanjutnya kita membahas binding, extractors, dan validation — memetakan body, query, header, dan URI ke struct Go, memakai paket extractor untuk mengambil nilai deklaratif, dan memvalidasi input dengan go-playground/validator.