В чём различия между Fiber v2 и его предшественником по API и функциональности?
Fiber v2 перешёл на модульную архитектуру с отдельными пакетами middleware, изменил сигнатуры обработчиков на возврат error, добавил Ctx.BodyParser, Generic-роуты и улучшил производительность за счёт fasthttp обновлений.
Fiber v2 vs v1: ключевые отличия
Fiber v2 — это не инкрементальное обновление, а переработка API с нарушением обратной совместимости. Изменения охватывают сигнатуры, middleware-экосистему, конфигурацию и обработку ошибок.
1. Сигнатура обработчика
Самое заметное изменение: handlers теперь возвращают error.
// v1
app.Get("/", func(c *fiber.Ctx) {
c.Send("hello")
})
// v2
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("hello")
})
Это позволяет централизованно обрабатывать ошибки через app.Use(ErrorHandler) и стандартный паттерн Go.
2. Централизованная обработка ошибок
app := fiber.New(fiber.Config{
ErrorHandler: func(c *fiber.Ctx, err error) error {
code := fiber.StatusInternalServerError
var e *fiber.Error
if errors.As(err, &e) {
code = e.Code
}
return c.Status(code).JSON(fiber.Map{"error": err.Error()})
},
})
В v1 ошибки нужно было обрабатывать внутри каждого обработчика вручную.
3. Middleware вынесены в отдельные репозитории
В v1 все middleware были частью основного пакета. В v2 каждый middleware живёт в github.com/gofiber/fiber/v2/middleware/:
import (
"github.com/gofiber/fiber/v2/middleware/cors"
"github.com/gofiber/fiber/v2/middleware/logger"
"github.com/gofiber/fiber/v2/middleware/recover"
"github.com/gofiber/fiber/v2/middleware/limiter"
)
app.Use(recover.New())
app.Use(logger.New(logger.Config{
Format: "${method} ${path} ${status} ${latency}\n",
}))
app.Use(cors.New(cors.Config{
AllowOrigins: "https://example.com",
AllowHeaders: "Origin, Content-Type, Authorization",
}))
app.Use(limiter.New(limiter.Config{
Max: 100,
Expiration: 1 * time.Minute,
}))
4. BodyParser и валидация
type LoginRequest struct {
Email string `json:"email" validate:"required,email"`
Password string `json:"password" validate:"required,min=8"`
}
app.Post("/login", func(c *fiber.Ctx) error {
var req LoginRequest
if err := c.BodyParser(&req); err != nil {
return fiber.NewError(fiber.StatusBadRequest, "invalid body")
}
// ...
return c.JSON(fiber.Map{"token": "..."})
})
В v1 парсинг тела требовал отдельного вызова c.JSON() только для отправки; входящий JSON парсился через c.BodyParser(), но API был менее стабильным.
5. Prefork и конфигурация приложения
app := fiber.New(fiber.Config{
Prefork: true, // SO_REUSEPORT, несколько процессов
CaseSensitive: true, // /User != /user
StrictRouting: true, // /foo/ != /foo
ServerHeader: "Fiber",
BodyLimit: 4 * 1024 * 1024, // 4 MB
ReadTimeout: 5 * time.Second,
WriteTimeout: 10 * time.Second,
DisableStartupMessage: false,
})
6. Новые методы Ctx
c.Bind()— привязка query/form/json из одного вызова (v2.50+)c.GetReqHeaders()— все заголовки как mapc.Protocol()— http или https с учётом X-Forwarded-Protoc.IsFromLocal()— проверка локального IPc.SaveFile()/c.SaveFileToStorage()— сохранение multipart
7. Маршрутизация
// Группы с middleware (v2 API стабилизирован)
api := app.Group("/api", authMiddleware)
v1 := api.Group("/v1")
v1.Get("/users", getUsers)
v1.Post("/users", createUser)
// Named параметры + regex
app.Get("/user/:id<int>", getUserById) // только числовые id
app.Get("/files/*", serveFiles) // wildcard
Подводные камни
- Миграция сигнатур: если вы копируете handler из v1-проекта, компилятор не сразу укажет на отсутствие
errorв возврате — типfunc(*fiber.Ctx)иfunc(*fiber.Ctx) errorнесовместимы. - c.Body() возвращает слайс байт: в v2 тело запроса доступно только до конца хендлера — после него буфер освобождается fasthttp. Если нужно хранить тело дольше, скопируйте его:
body := make([]byte, len(c.Body())); copy(body, c.Body()). - Prefork на Windows:
Prefork: trueне работает на Windows (нетSO_REUSEPORT). Приложение упадёт с ошибкой при старте. - c.Locals() и горутины: передавать
*fiber.Ctxв горутины опасно — контекст переиспользуется пулом. Копируйте нужные данные в переменные до запуска горутины. - Изменение импортного пути: v2 использует
github.com/gofiber/fiber/v2, а неgithub.com/gofiber/fiber. Забытый старый импорт тихо компилируется с другим API. - Middleware порядок:
recover.New()нужно регистрировать первым, до всех остальных middleware — иначе паника в cors или logger не будет поймана. - fiber.Error vs обычный error:
fiber.NewError(404, "not found")автоматически устанавливает HTTP-статус в ErrorHandler; обычныйerrors.New()даст 500.
Common mistakes
- Давать ответ про различия Fiber v2 и v1 только на уровне определения, не показывая поведение в реальном приложении.
- Игнорировать границы ответственности вокруг темы «различия Fiber v2 и v1»: кто отменяет работу, кто владеет ресурсом и где формируется ответ клиенту.
- Не связывать различия Fiber v2 и v1 с observability, тестированием или безопасностью, когда это влияет на продакшен-поведение.
What the interviewer is testing
- Точно объясняет, что именно делает различия Fiber v2 и v1 и где это используется в Go-коде.
- Связывает различия Fiber v2 и v1 с корректным lifecycle запроса, отменой, конкурентностью или конфигурацией сервера там, где это уместно.
- Не изобретает API и опирается на реальные контракты официальной документации.