Fiber — cepat, dengan konsekuensi
Fiber terasa seperti Express dan menang di benchmark. Yang perlu dipahami sebelum memilihnya: ia berada di luar ekosistem net/http, dan konsekuensinya menyentuh HTTP/2, middleware, dan cara data dipegang.
Intisari
- Fiber memakai fasthttp, bukan
net/http— middleware, pustaka, dan contoh dari ekosistem Go standar tidak langsung bekerja. - fasthttp tidak mendukung HTTP/2. Untuk aplikasi web modern ini pembatas nyata.
- Buffer permintaan dipakai ulang: nilai dari
c.Params/c.Bodytidak boleh disimpan tanpa disalin. - Keunggulan performanya nyata hanya pada beban yang didominasi parsing HTTP — proksi, gateway, endpoint sangat ringan.
- Untuk aplikasi web yang bicara ke database, keunggulan itu hilang di derau.
Bentuknya
import "github.com/gofiber/fiber/v2"
app := fiber.New(fiber.Config{
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
BodyLimit: 1 * 1024 * 1024,
ErrorHandler: penanganError,
})
app.Use(recover.New())
app.Use(requestid.New())
api := app.Group("/api/v1")
api.Get("/produk/:id", h.AmbilProduk)
app.Listen(":8080")
func (h *Handler) AmbilProduk(c *fiber.Ctx) error {
id, err := strconv.ParseInt(c.Params("id"), 10, 64)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "id tidak valid")
}
p, err := h.produk.Ambil(c.UserContext(), id) // BUKAN c.Context()
if err != nil {
return err
}
return c.JSON(keResp(p))
}
Konsekuensi memakai fasthttp
| Hal | Akibatnya |
|---|---|
Bukan http.Handler | Middleware dan pustaka net/http perlu adaptor, sebagian tidak bisa sama sekali |
| Tanpa HTTP/2 | Tidak ada multiplexing; gRPC tidak bisa; harus diterminasi di CDN/ALB |
httptest tidak berlaku | Tes memakai app.Test() milik Fiber |
| Buffer dipakai ulang | Nilai harus disalin sebelum disimpan atau dikirim ke goroutine |
| Dua jenis context | c.Context() milik fasthttp; yang setara context.Context adalah c.UserContext() |
| Ekosistem observability | Instrumentasi OpenTelemetry untuk net/http tidak langsung terpakai |
// ❌ nilai ini menunjuk buffer yang akan dipakai permintaan BERIKUTNYA
nama := c.Params("nama")
go simpan(nama)
// ✅ salin dulu
nama := utils.CopyString(c.Params("nama"))
go simpan(nama)
Kelas bug ini mirip dengan c.Copy() di Gin, tapi lebih luas: di Fiber ia berlaku
untuk string yang kamu ambil dari permintaan, bukan hanya objek konteks. Gejalanya paling jahat
— data yang benar 999 kali dan tertukar sekali, di bawah beban.
Kapan Fiber masuk akal
| Beban | Fiber menang? |
|---|---|
| Proksi / gateway, ratusan ribu permintaan per detik | Ya — parsing HTTP memang porsi terbesar |
| Endpoint sangat ringan (health, redirect, echo) | Ya |
| API yang memanggil database | Tidak — kueri mendominasi total waktu |
| Aplikasi yang butuh HTTP/2 atau gRPC | Tidak bisa |
| Tim yang datang dari Express | Terasa familiar — tapi timbang biayanya |
Uji kelayakan sebelum memilih: ukur berapa persen waktu permintaanmu yang benar-benar habis di
lapisan HTTP. Kalau di bawah 5% — dan di aplikasi yang menyentuh database, hampir selalu di bawah 1% —
maka framework tercepat sekalipun hanya bisa memperbaiki angka itu. Yang kamu bayar sebagai gantinya
adalah keluar dari ekosistem net/http untuk selamanya.
Latihan: tulis endpoint yang sama di chi dan di Fiber, keduanya menjalankan satu kueri
Postgres, lalu bandingkan dengan hey -n 5000 -c 50. Catat selisih p95-nya, lalu bandingkan
selisih itu dengan waktu kueri kamu. Angka itulah yang seharusnya jadi dasar keputusan.
Rangkuman ini sengaja dipangkas ke bagian yang dipakai di roadmap. Buka sumber aslinya saat kamu butuh detail lengkap atau referensi parameter.