Перейти к основному содержимому

Первая программа на Fiber

Разработчику Архитектору

Статья показывает, как быстро собрать рабочий API на Fiber и при этом понимать архитектурные компромиссы. Это полезно, когда нужно выбрать стек под высокую нагрузку и не потерять управляемость проекта.


Первая программа на Fiber

Где применяют Fiber

Fiber (github.com/gofiber/fiber/v2) заточен под высокую пропускную способность (много запросов в секунду). Внутри используется fasthttp, а не стандартный net/http из Go. API намеренно похож на Express в Node.js: app.Get, app.Group, c.JSON.

Цена скорости: middleware и библиотеки из экосистемы net/http напрямую не подключаются; HTTP/2 часто терминируют на reverse proxy (nginx, Envoy). Для нового микросервиса без legacy — разумный выбор; для встраивания в старый http.ServeMuxEcho или Gin.

Обзор: Фреймворки и библиотеки Go · тесты: Тестирование в Go.


Что получится

Тот же API "Заметки", порт 3000 (в примерах Fiber часто используют 3000, в отличие от 8080 у Gin/Echo).


Термины

ТерминПростыми словами
fasthttpАльтернативный HTTP-движок; быстрее в бенчмарках, другой API
*fiber.CtxКонтекст запроса: Params, BodyParser, JSON
fiber.MapСокращение для map[string]interface{} в JSON-ответах
BodyParserРазбор тела (JSON, form) в struct
RPSRequests per second — запросов в секунду

Инициализация

mkdir fiber-notes && cd fiber-notes
go mod init example.com/fiber-notes
go get github.com/gofiber/fiber/v2

Разбор:

  • mkdir ... && cd ... создаёт изолированное пространство проекта и сразу переводит терминал в рабочую папку.
  • go mod init запускает модульный режим Go и фиксирует имя модуля для импорта локальных пакетов.
  • go get github.com/gofiber/fiber/v2 добавляет Fiber как внешнюю зависимость в go.mod.
  • После этого шага можно создать main.go и выполнить локальный запуск через go run ..

Структура учебного проекта

Чтобы код не превращался в один длинный main.go, сразу разделяйте:

  • main.go — создание fiber.App и регистрация роутов;
  • handlers.go — HTTP-обработчики;
  • store.go — хранение данных и синхронизация;
  • models.go — структуры Note, NoteCreate.

Даже для небольшого примера это делает материал более читаемым и масштабируемым.


REST API "Заметки"

Код ITЗагрузка примера кода…

Разбор:

  • fiber.New() создаёт экземпляр приложения и внутренний роутер.
  • app.Get("/health", ...) регистрирует endpoint проверки состояния и возвращает JSON через fiber.Map.
  • api := app.Group("/api") добавляет префикс к связанным маршрутам, чтобы структура URL была читаемой.
  • Методы Get, Post, Delete явно связывают HTTP-метод и путь с функцией-обработчиком.
  • app.Listen(":3000") запускает сервер на 3000 порту и удерживает процесс активным.

Разбор main

СтрокаСмысл
fiber.New()Создание приложения (можно передать конфиг)
app.Get / Post / DeleteРегистрация маршрута; метод с заглавной буквы
app.Group("/api")Общий префикс для заметок
app.Listen(":3000")Блокирующий запуск сервера

Handlers

Код ITЗагрузка примера кода…

Разбор:

  • var body NoteCreate готовит структуру, в которую будет разобран JSON-запрос.

  • c.BodyParser(&body) извлекает данные из тела запроса и заполняет поля структуры.

  • Ветка if body.Text == "" реализует ручную валидацию бизнес-правила "текст обязателен".

  • Блок с mu.Lock() защищает разделяемые данные (notes, nextID) от конкурентной записи.

  • c.Status(...).JSON(...) строит ответ цепочкой: сначала статус, затем JSON-тело.

  • Возврат fiber.StatusCreated (201) показывает успешное создание ресурса.

  • BodyParser — аналог ShouldBindJSON / Bind: нужен заголовок Content-Type: application/json.

  • Проверка body.Text == "" — ручная валидация; в Gin/Echo часто делают через теги.

  • Цепочка c.Status(...).JSON(...) — сначала код ответа, потом тело.

Параметр пути: c.Params("id"), не c.Param как в Gin/Echo.

go run .

Разбор:

  • go run . выполняет быструю сборку и немедленно стартует приложение.
  • Команда полезна для итеративной разработки, когда часто меняется код.
  • Текущая директория должна содержать go.mod и пакет main.
  • При успешном запуске Fiber начинает слушать порт 3000, указанный в app.Listen.

Проверка

curl http://127.0.0.1:3000/health
curl http://127.0.0.1:3000/api/notes
curl -X POST http://127.0.0.1:3000/api/notes \
-H "Content-Type: application/json" \
-d '{"text":"Изучить Fiber"}'

Разбор:

  • Первый запрос валидирует, что процесс отвечает и маршрут /health подключён корректно.
  • Второй проверяет чтение ресурса коллекции через группу /api.
  • Третий отправляет JSON-тело и тестирует создание заметки по POST.
  • Заголовок Content-Type: application/json обязателен для корректного парсинга тела.
  • Набор команд удобно использовать как минимальную ручную проверку после каждого изменения.

Порт 3000 — не путайте с примерами Gin/Echo на 8080.


Middleware из экосистемы Fiber


import "github.com/gofiber/fiber/v2/middleware/cors"
import "github.com/gofiber/fiber/v2/middleware/logger"

app.Use(logger.New())
app.Use(cors.New())

Разбор:

  • Импорты подключают готовые middleware из экосистемы Fiber.
  • logger.New() добавляет логирование входящих запросов и их статусов.
  • cors.New() управляет политикой cross-origin вызовов из браузера.
  • app.Use(...) вешает middleware на все последующие маршруты приложения.
  • Такой слой обычно подключают в main до регистрации бизнес-роутов.

CORS — разрешение браузеру вызывать API с другого origin (фронт на localhost:5173, API на 3000). Logger — лог запросов, аналог встроенного лога в gin.Default().

Middleware из пакетов net/http без адаптера с Fiber не совместимы.


Ограничения (важно до продакшена)

  • Fiber не вставляется в существующий http.ServeMux без отдельного адаптера.
  • HTTP/2 к fasthttp напрямую ограничен — перед сервисом часто ставят nginx с TLS и HTTP/2 на стороне прокси.
  • Библиотеки, завязанные только на *http.Request, потребуют обёртки или замены.

Для совместимости со стандартной библиотекой смотрите Echo.


Частые ошибки

СимптомПричина
Middleware из net/http не работаетДругой стек — только Fiber-middleware или адаптер
Cannot GET /api/notesМаршрут зарегистрирован вне Group("/api")
Тело POST пустоеНет BodyParser или неверный Content-Type
curl на 8080 при Listen :3000Неверный порт в URL

Что попробовать

  1. Подключить middleware/compress для gzip-ответов.
  2. Сравнить латентность с Echo на том же железе (hey, ab — осторожно с выводами на учебном коде).
  3. Написать интеграционный тест через app.Test(req) (встроенный helper Fiber).

Мини-чек-лист production-ready

  • Подключён recover middleware для перехвата паник.
  • Логи в JSON или стабильном формате для централизованного сбора.
  • Ограничен размер входящего тела запроса.
  • Настроены таймауты и reverse proxy перед сервисом.
  • Ошибки API отдаются в единой структуре { "error": "..." }.

Дополнительные сниппеты с разбором

Пример — recover middleware для Fiber


import "github.com/gofiber/fiber/v2/middleware/recover"

app := fiber.New()
app.Use(recover.New())

Разбор:

  • recover.New() подключает перехват паник внутри обработчиков Fiber.
  • app.Use(...) регистрирует middleware на всё приложение до бизнес-маршрутов.
  • При panic сервер продолжает работу и отдаёт контролируемый HTTP-ответ вместо падения процесса.
  • Такой слой особенно важен для публичных API, где единичная ошибка не должна ронять сервис.
  • Подключение recover обычно сочетают с централизованным логированием причины panic.

Пример — ограничение размера тела запроса

app := fiber.New(fiber.Config{
BodyLimit: 1 * 1024 * 1024, // 1 MB
})

Разбор:

  • fiber.Config позволяет задать глобальные ограничения приложения при создании fiber.App.
  • BodyLimit ограничивает максимальный размер входящего тела в байтах.
  • Лимит уменьшает риск чрезмерной нагрузки на память от больших payload.
  • Число 1 * 1024 * 1024 делает размер читаемым и снижает вероятность ошибки в "магическом" литерале.
  • Такой параметр стоит выбирать по контракту API и типичным сценариям клиентов.

Пример — простой route-параметр в Fiber

app.Get("/notes/:id", func(c *fiber.Ctx) error {
id := c.Params("id")
return c.JSON(fiber.Map{"id": id})
})

Разбор:

  • "/notes/:id" объявляет динамический сегмент пути с именем id.
  • c.Params("id") извлекает значение параметра как строку из URL.
  • Возврат c.JSON(...) формирует JSON-ответ без ручной сериализации.
  • fiber.Map удобен для коротких ответов в учебных примерах и прототипах.
  • В реальном handler после чтения параметра обычно делают Atoi и проверку корректности идентификатора.

Дальше


Основа по протоколу

Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.


В подборках

Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:

Первые шаги (маршрут подборки) — Первая программа на Echo, Первая программа на Axum, Первая программа на Gin, Первая программа Electron с React, Spring Boot на Kotlin — первая программа, Первая программа на React Native.