diff --git a/main_dc/yalarba/api_yal/internal/router/router.go b/main_dc/yalarba/api_yal/internal/router/router.go index 61ead1b..78a2432 100644 --- a/main_dc/yalarba/api_yal/internal/router/router.go +++ b/main_dc/yalarba/api_yal/internal/router/router.go @@ -12,97 +12,163 @@ 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) }) }) -} \ No newline at end of file +}