modified: main_dc/yalarba/api_yal/internal/router/router.go

add comments and loggs for middleware func
This commit is contained in:
2026-03-09 02:36:21 +05:00
parent 74b46a5109
commit e9a21c758d
@@ -12,96 +12,162 @@ import (
"github.com/go-chi/chi/v5"
ChiMiddleware "github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/cors"
"go.uber.org/zap"
"gorm.io/gorm"
)
// SetupRouter инициализирует и настраивает основной маршрутизатор приложения
// Параметры:
// - db: подключение к базе данных GORM
// - config: конфигурация приложения
//
// Возвращает:
// - http.Handler: настроенный маршрутизатор с применёнными middleware и маршрутами
func SetupRouter(db *gorm.DB, config *config.Config) http.Handler {
// Получаем экземпляр логгера для записи событий
zapLogger := logger.Get()
zapLogger.Info("Start setup routers")
zapLogger.Info("Начало настройки маршрутов")
// Создаём новый экземпляр маршрутизатора chi
r := chi.NewRouter()
// Добавляем все production middleware
// Добавляем все production middleware для обработки входящих запросов
addProductionMiddleware(r, config)
zapLogger.Debug("Production middleware успешно добавлены")
// Health check
// Эндпоинт для проверки работоспособности сервиса (health check)
// Используется мониторингом и системами оркестрации для проверки статуса приложения
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(map[string]string{"status": "healthy"})
// Формируем и отправляем JSON-ответ со статусом healthy
if err := json.NewEncoder(w).Encode(map[string]string{"status": "healthy"}); err != nil {
// Логируем ошибку при невозможности отправить ответ
zapLogger.Error("Ошибка при отправке health check ответа",
zap.String("path", r.URL.Path),
zap.Error(err),
)
}
})
zapLogger.Debug("Health check маршрут зарегистрирован")
// Auth middleware
// Добавляем middleware для аутентификации ко всем последующим маршрутам
// Все маршруты после этого middleware будут требовать валидный контекст аутентификации
r.Use(CastomMiddleware.AuthMiddlewareWithContext)
zapLogger.Debug("Auth middleware применён ко всем маршрутам")
zapLogger.Info("End setup routers")
// TODO: Здесь можно добавить регистрацию дополнительных маршрутов
// Например: r.Mount("/api/v1", apiRoutes(db, config))
// Логируем все зарегистрированные маршруты
zapLogger.Info("Настройка маршрутов завершена успешно")
// Логируем все зарегистрированные маршруты для отладки и мониторинга
routeLogger := logger.NewRouteLogger(logger.NewWrapper(zapLogger))
routeLogger.LogRoutes(r)
zapLogger.Debug("Все маршруты залогированы")
return r
}
// addProductionMiddleware добавляет все необходимые middleware для production окружения
// Функция применяет стандартный набор middleware для обработки запросов:
// - Идентификация запросов
// - Логирование
// - Безопасность
// - Сжатие ответов
// - CORS настройки
//
// Параметры:
// - r: экземпляр маршрутизатора chi
// - config: конфигурация приложения для настройки middleware под окружение
func addProductionMiddleware(r *chi.Mux, config *config.Config) {
// Request ID middleware - добавляет уникальный ID к каждому запросу
// Позволяет отслеживать запрос на протяжении всего жизненного цикла
r.Use(ChiMiddleware.RequestID)
// Real IP middleware - корректно определяет реальный IP клиента (за прокси)
// Важно для правильного логирования и rate limiting'а
r.Use(ChiMiddleware.RealIP)
// Logger middleware - логирует все запросы в формате Apache
// Предоставляет базовую информацию о входящих запросах
r.Use(ChiMiddleware.Logger)
// Recoverer middleware - восстанавливает после паники и возвращает 500
// Предотвращает падение всего приложения из-за паники в обработчиках
r.Use(ChiMiddleware.Recoverer)
// Timeout middleware - устанавливает таймаут на запросы (30 секунд)
// Защищает от "висящих" запросов, которые могут занять слишком много времени
r.Use(ChiMiddleware.Timeout(30 * time.Second))
// Compress middleware - сжимает ответы (gzip)
// Уменьшает размер передаваемых данных, улучшает производительность
// Уровень сжатия 5 (среднее между скоростью и степенью сжатия)
r.Use(ChiMiddleware.Compress(5, "gzip"))
// StripSlashes middleware - удаляет слеши в конце URL или редиректит
// Нормализует URL'ы для единообразия маршрутизации
r.Use(ChiMiddleware.StripSlashes)
// CORS middleware - настройка CORS для production
// Позволяет контролировать доступ к API из браузерных приложений
r.Use(cors.Handler(cors.Options{
AllowedOrigins: config.CORS.AllowedOrigins,
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"},
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "X-Request-ID"},
ExposedHeaders: []string{"Link", "X-Request-ID"},
// Разрешённые источники (origins) из конфигурации
AllowedOrigins: config.CORS.AllowedOrigins,
// Разрешённые HTTP методы
AllowedMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH"},
// Разрешённые заголовки запросов
AllowedHeaders: []string{"Accept", "Authorization", "Content-Type", "X-CSRF-Token", "X-Request-ID"},
// Заголовки, доступные клиенту при чтении ответа
ExposedHeaders: []string{"Link", "X-Request-ID"},
// Разрешить передачу cookies и HTTP-аутентификацию
AllowCredentials: true,
MaxAge: 300,
// Время кэширования preflight запросов (в секундах)
MaxAge: 300,
}))
// Content-Type middleware - проверяет Content-Type для POST/PUT запросов
// Гарантирует, что клиенты отправляют данные в ожидаемом формате
r.Use(ChiMiddleware.AllowContentType("application/json", "application/xml"))
// Дополнительные middleware в зависимости от конфигурации
if config.Environment == "development" {
// Добавляем дополнительное логирование для разработки
// В dev-режиме полезно иметь более подробную информацию о запросах
r.Use(ChiMiddleware.Logger)
}
if config.RateLimit.Enabled {
// Добавляем rate limiting если включено в конфиге
// Защищает от DDoS атак и чрезмерного использования ресурсов
r.Use(ChiMiddleware.Throttle(config.RateLimit.RequestsPerSecond))
}
// Security headers middleware
// Security headers middleware - добавляет заголовки безопасности к каждому ответу
// Защищает от распространённых веб-уязвимостей
r.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Защита от MIME-снiffing атак
w.Header().Set("X-Content-Type-Options", "nosniff")
// Защита от clickjacking атак
w.Header().Set("X-Frame-Options", "DENY")
// Включает защиту от XSS в браузерах
w.Header().Set("X-XSS-Protection", "1; mode=block")
// Контролирует, сколько информации о реферере передаётся при переходах
w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
// Для production окружения включаем HSTS (HTTP Strict Transport Security)
// Заставляет браузер использовать только HTTPS соединения
if config.Environment == "production" {
w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
}
// Передаём управление следующему middleware или обработчику
next.ServeHTTP(w, r)
})
})