← Назад к вопросам

Какой используешь роутер?

1.0 Junior🔥 161 комментариев
#Сетевые протоколы и API

Комментарии (1)

🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Отличный и очень практичный вопрос. Я использую и рекомендую chi (произносится "кай") от автора Peter Bourgon в подавляющем большинстве проектов, так как он идеально соответствует философии Go: простота, производительность и композиция через интерфейсы.

Однако выбор роутера — это не догма, а инженерное решение, зависящее от контекста. Вот мой подробный анализ.

Почему chi — мой основной выбор

chi — это легковесный, идиоматический и мощный HTTP-роутер, построенный на стандартном контексте net/http. Это не фреймворк, а библиотека для маршрутизации и middleware.

Ключевые преимущества

  1. Совместимость с net/http. chi.Router реализует стандартный интерфейс http.Handler. Это означает:
    * Полная интеграция со всей экосистемой Go.
    * Вы можете постепенно внедрить `chi` в существующий проект.
    * Легко тестировать с помощью `net/http/httptest`.
```go
// Это стандартный http.Handler
r := chi.NewRouter()
r.Get("/users", myHandler)
http.ListenAndServe(":3000", r) // r можно использовать напрямую
```

2. Идиоматичный и выразительный синтаксис. Он интуитивно понятен и позволяет создавать вложенные структуры маршрутов, что отлично ложится на RESTful-дизайн. go r := chi.NewRouter() r.Route("/api", func(r chi.Router) { r.Use(AuthMiddleware) // Middleware только для /api r.Route("/users", func(r chi.Router) { r.Get("/", listUsers) // GET /api/users r.Post("/", createUser) // POST /api/users r.Route("/{id}", func(r chi.Router) { r.Get("/", getUser) // GET /api/users/123 r.Put("/", updateUser) // PUT /api/users/123 r.Delete("/", deleteUser) // DELETE /api/users/123 }) }) })

  1. Мощная и простая система middleware. Middleware — это просто функции func(http.Handler) http.Handler, что снова соответствует стандарту. chi предоставляет полезные готовые middleware (логгер, восстановление после паники, сжатие) и позволяет легко писать свои.

    // Собственный middleware для логирования
    func LoggerMiddleware(next http.Handler) http.Handler {
      return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        next.ServeHTTP(w, r)
        log.Printf("[%s] %s %v", r.Method, r.URL.Path, time.Since(start))
      })
    }
    r.Use(LoggerMiddleware)
    
  2. Высокая производительность. Алгоритм маршрутизации основан на Radix tree (префиксном дереве), что делает сопоставление URL очень быстрым, сравнимым с http.ServeMux или gorilla/mux.

  3. Встроенный контекст для передачи значений. Он безопасно использует context.Context для передачи значений между middleware и хендлерами (например, аутентифицированный пользователь).

    r.With(UserCtx).Get("/admin", adminHandler)
    // ...
    func adminHandler(w http.ResponseWriter, r *http.Request) {
      user := r.Context().Value("user").(*User) // Безопасное извлечение
      // ...
    }
    

Когда я рассматриваю другие варианты

Хотя chi — отличный универсальный инструмент, бывают случаи для иного выбора.

1. Стандартный http.ServeMux

  • Когда использовать: Для микро-сервисов, простых API, утилит или когда требуется абсолютный минимализм и нулевые зависимости.
  • Плюсы: В составе стандартной библиотеки, нет зависимостей, предельно прост.
  • Минусы: Нет поддержки параметров в пути (/users/{id}), вложенных маршрутов, стандартизированного подхода к middleware.

2. gin (https://github.com/gin-gonic/gin)

  • Когда использовать: Для высоконагруженных HTTP-сервисов, где важна максимальная raw-производительность, или когда нужны встроенные возможности "батареек" (биндинг JSON, валидация, рендеринг шаблонов).
  • Плюсы: Очень высокая скорость за счёт собственного оптимизированного контекста и пулинга, богатый набор встроенных утилит, огромное сообщество.
  • Минусы: Собственный контекст (не context.Context до недавних версий), что может создать сложности при интеграции с другими библиотеками. Более "тяжёлый" и фреймворко-подобный подход.

3. gorilla/mux (https://github.com/gorilla/mux)

  • Когда использовать: В legacy-проектах или когда требуется очень специфичное, сложное сопоставление маршрутов по регулярным выражениям или условиям.
  • Плюсы: Невероятно гибкий и мощный в сопоставлении маршрутов, проверен годами.
  • Минусы: Медленнее chi и gin, менее идиоматичен с точки зрения middleware, развитие проекта в последние годы замедлилось.

4. fiber (https://github.com/gofiber/fiber)

  • Когда использовать: Для команды, пришедшей из Node.js (Express), где важна привычная семантика и синтаксическая скорость разработки, или в проектах, где критична эффективность использования памяти (вдохновлен Express и построен на Fasthttp).
  • Плюсы: Очень высокая производительность, выразительный API, похожий на Express/Кoa.
  • Минусы: Построен на Fasthttp, а не на net/http. Это означает несовместимость с огромной экосистемой Go-библиотек, написанных под стандартный интерфейс. Это самый большой риск и ограничение.

Мой итоговый подход

Моя стратегия выбора выглядит так:

  1. По умолчанию — chi. Он обеспечивает идеальный баланс между простотой, производительностью, совместимостью и выразительностью. Он учит правильно использовать net/http и context.Context.
  2. Для максимальной производительности в синтетических тестах — gin. Если benchmarks — абсолютный приоритет и команда готова к его экосистеме.
  3. Для абсолютной простоты или учебных проектов — http.ServeMux. Чтобы понять основы.
  4. fiber и аналоги на Fasthttp — только в изолированных проектах, где вы точно знаете, что не будете подключать сторонние middleware или клиенты, работающие с net/http.

Ключевой вывод: В Go роутер — это не центр архитектуры, как во многих фреймворках. Это всего лишь компонент для диспетчеризации запросов. Ваша бизнес-логика должна зависеть от стандартных интерфейсов http.Handler и context.Context, и тогда смена роутера станет делом замены нескольких строк в main.go. chi, будучи полностью совместимым со стандартом, идеально вписывается в эту философию.

Какой используешь роутер? | PrepBro