Backend на Go Fiber: продуктивність і JWT-авторизація — типовий стек, коли Node.js-сервіс упирається в ліміти, а міграція на Go здається складною. Fiber дає міст: знайомий Express API, але з продуктивністю fasthttp. Ми використовуємо Fiber для високонавантажених проєктів уже 5+ років і готові поділитися досвідом на 20+ живих проєктів.
Один із кейсів — інтернет-магазин з піковим навантаженням 10 000 RPS. Перехід з Express на Fiber знизив час відповіді на 40% і споживання пам'яті на 30%. При цьому команда Node.js-розробників освоїла Fiber за тиждень завдяки знайомому синтаксису. Зниження витрат на хмарні ресурси становило близько 300–500 usd на місяць за рахунок меншого споживання пам'яті, а повна міграція окупилася за 3 місяці при бюджеті 12 000 usd.
Чому Fiber працює швидше net/http
Fiber — Go-фреймворк, натхненний Express.js. Якщо розробник прийшов із Node.js, API здасться знайомим. Всередині — fasthttp замість стандартного net/http, що дає ~2x приріст у синтетичних тестах на чистому HTTP. У реальних проєктах з PostgreSQL і Redis різниця менша, але Fiber все одно один із найшвидших Go-фреймворків. Згідно з офіційними бенчмарками Fiber, він обробляє ~400 000 запитів/сек проти ~200 000 у Gin. Ми впровадили його в 10+ комерційних проєктах і помітили зниження споживання пам'яті до 30%.
Важливий нюанс: fasthttp несумісний із net/http middleware. Це означає, що частина Go-екосистеми (наприклад, стандартні OpenTelemetry middleware під net/http) не працює напряму — потрібні адаптери або Fiber-специфічні пакети.
Реалізація JWT-авторизації в Fiber
Крок 1: Ініціалізація додатку
package main
import (
"log"
"os"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/compress"
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/helmet"
"github.com/gofiber/fiber/v2/middleware/logger"
"github.com/gofiber/fiber/v2/middleware/recover"
"github.com/gofiber/fiber/v2/middleware/limiter"
)
func main() {
app := fiber.New(fiber.Config{
AppName: "MyAPI v1.0",
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
IdleTimeout: 120 * time.Second,
BodyLimit: 4 * 1024 * 1024, // 4MB
ErrorHandler: customErrorHandler,
DisableStartupMessage: true,
})
app.Use(recover.New())
app.Use(helmet.New())
app.Use(compress.New(compress.Config{Level: compress.LevelBestSpeed}))
app.Use(cors.New(cors.Config{
AllowOrigins: os.Getenv("ALLOWED_ORIGINS"),
AllowCredentials: true,
AllowHeaders: "Origin, Content-Type, Authorization",
}))
app.Use(logger.New(logger.Config{
Format: "${time} | ${status} | ${latency} | ${method} ${path}\n",
}))
app.Use(limiter.New(limiter.Config{Max: 100, Expiration: 60 * time.Second}))
setupRoutes(app)
log.Fatal(app.Listen(":8080"))
}
Крок 2: Роутинг і групування
func setupRoutes(app *fiber.App) {
api := app.Group("/api/v1")
// Публічні
api.Post("/auth/login", authHandler.Login)
api.Post("/auth/refresh", authHandler.Refresh)
// З JWT middleware
api.Get("/products", productHandler.List)
api.Get("/products/:id", productHandler.Get)
protected := api.Group("/", jwtMiddleware)
protected.Get("/profile", authHandler.Profile)
admin := api.Group("/admin", jwtMiddleware, roleMiddleware("admin"))
admin.Post("/products", productHandler.Create)
admin.Put("/products/:id", productHandler.Update)
admin.Delete("/products/:id", productHandler.Delete)
}
Крок 3: Handlers
Handlers ми тримаємо тонкими: BodyParser в input-структуру з тегами validate, validator.Struct для перевірки, виклик сервісу, маппінг доменних помилок у HTTP-статуси. Пагінація — через c.QueryInt("page", 1) і c.QueryInt("limit", 20) з верхнім обмеженням 100 записів на сторінку. Відповідь формується через fiber.Map з ключами data і pagination, щоб фронтенд отримував єдиний формат. Помилки валідації повертаємо зі статусом 422 і полем errors — масив по 3–5 полів на запит. На кожен handler припадає близько 30–40 рядків коду, що зручно для code review і типового тестування.
Крок 4: JWT middleware
package middleware
import (
"strings"
"github.com/gofiber/fiber/v2"
"github.com/golang-jwt/jwt/v5"
)
func JWTMiddleware(secret string) fiber.Handler {
return func(c *fiber.Ctx) error {
auth := c.Get("Authorization")
if !strings.HasPrefix(auth, "Bearer ") {
return fiber.ErrUnauthorized
}
token, err := jwt.Parse(auth[7:], func(t *jwt.Token) (interface{}, error) {
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
return nil, fiber.ErrUnauthorized
}
return []byte(secret), nil
})
if err != nil || !token.Valid {
return fiber.ErrUnauthorized
}
claims := token.Claims.(jwt.MapClaims)
c.Locals("userID", int(claims["sub"].(float64)))
c.Locals("role", claims["role"])
return c.Next()
}
}
Які є обмеження у fasthttp?
fasthttp перевикористовує об'єкти request/context для зниження GC-pressure. Це потребує обережності: не можна захоплювати *fiber.Ctx у горутини без c.Copy(). При передачі контексту в async-операції:
func (h *Handler) AsyncProcess(c *fiber.Ctx) error {
// НЕ робіть так — ctx буде перевикористаний до завершення горутини
// go func() { h.svc.Process(c) }()
// Робіть копію
cc := c.Copy()
go func() {
h.svc.ProcessAsync(context.Background(), cc.Body())
}()
return c.SendStatus(fiber.StatusAccepted)
}
Production-конфігурація для HTTPS
Для продакшену рекомендується використовувати TLS через зворотний проксі (Nginx) або вбудоване слухання:
app.ListenTLS(":443", "/path/to/cert.pem", "/path/to/key.pem")
Що входить в розробку
Порядок робіт фіксуємо в SoW з чек-листом deliverables:
- Проєктування архітектури: схема БД у dbdiagram, специфікація OpenAPI 3.1, діаграма сервісів.
- Налаштування Fiber-додатку: middleware стек (CORS, logger, recover, limiter), конфігурація timeout.
- Реалізація домену: handlers, сервіси, репозиторії з pgx і транзакціями.
- Авторизація: JWT access + refresh, рольова модель, blacklist через Redis.
- Тестування та деплой: unit + integration (100+ кейсів), Dockerfile, CI/CD у GitHub Actions.
| Етап | Результат |
|---|---|
| Архітектура | Схема БД, документація API (OpenAPI) |
| Middleware | CORS, логування, ліміти, безпека |
| Бізнес-логіка | Handlers, сервіси, репозиторії |
| Авторизація | JWT з ролями, refresh-токени |
| Завантаження файлів | Валідація, сховище (S3/local) |
| Тестування | Unit + integration тести (100+ кейсів) |
| Деплой | Dockerfile, CI/CD, моніторинг |
Терміни розробки
| Робота | Час |
|---|---|
| Налаштування + middleware + роути | 3–5 днів |
| Handlers + сервісний шар | 1–2 тижні |
| Repository + pgx | 3–5 днів |
| Auth + кеш | 3–5 днів |
| Тести | 1 тиждень |
API для сайту: 4–8 тижнів. Fiber добре підходить командам із Node.js-бекграундом, що переходять на Go, і проєктам з екстремальними вимогами до RPS. Ми маємо досвід із Go понад 5 років і гарантуємо якість коду.
Отримайте консультацію та оцінку за 1 день. Зв'яжіться з нами для обговорення вашого проєкту.
Додатково закриваємо observability-контур: підключаємо OpenTelemetry через Fiber-адаптери, відправляємо трейси в Jaeger або Grafana Tempo, експортуємо метрики Prometheus через /metrics. Для високонавантажених API додаємо connection pool pgxpool з 25–50 з'єднаннями та pgbouncer у transaction mode перед PostgreSQL — це витримує піки до 15 000 RPS без деградації p95. Логи структуруємо через zerolog у JSON, щоб Loki і ClickHouse могли їх індексувати за 8–10 полями. Окремо закладаємо graceful shutdown з 30-секундним drain, щоб Kubernetes rollout не рвав відкриті з'єднання. Всі ці деталі фіксуємо в runbook на 15–20 сторінок, який залишається у команди замовника та оновлюється протягом 3 місяців гарантійної підтримки.







