Files
tp/main_dc/yalarba/api_yal/internal/router/router.go
T
valitovgaziz 75b2f3f6b2 On branch main
modified:   main_dc/yalarba/api_yal/internal/domain/account/dto.go
	new file:   main_dc/yalarba/api_yal/internal/domain/account/errors.go
	modified:   main_dc/yalarba/api_yal/internal/domain/account/handler.go
	modified:   main_dc/yalarba/api_yal/internal/domain/account/router.go
	modified:   main_dc/yalarba/api_yal/internal/domain/account/service.go
	new file:   main_dc/yalarba/api_yal/internal/domain/account/types.go
	new file:   main_dc/yalarba/api_yal/internal/middleware/admin.go
	modified:   main_dc/yalarba/api_yal/internal/middleware/auth.go
	new file:   main_dc/yalarba/api_yal/internal/middleware/context.go
	new file:   main_dc/yalarba/api_yal/internal/middleware/logging.go
	modified:   main_dc/yalarba/api_yal/internal/router/router.go
last but not yet commit
2026-03-31 09:43:18 +05:00

111 lines
3.8 KiB
Go

package router
import (
"api_yal/internal/config"
"api_yal/internal/logger"
"api_yal/internal/domain/auth"
"api_yal/internal/domain/account"
"time"
"encoding/json"
"net/http"
"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 инициализирует и настраивает основной маршрутизатор приложения
func SetupRouter(db *gorm.DB, config *config.Config) http.Handler {
zapLogger := logger.Get()
zapLogger.Info("Начало настройки маршрутов")
r := chi.NewRouter()
// ВСЕ middleware должны быть определены ДО маршрутов
// 1. Сначала добавляем production middleware
addProductionMiddleware(r, config)
// 2. Затем добавляем middleware аутентификации (он тоже применяется ко всем маршрутам)
zapLogger.Debug("Auth middleware применён")
// 3. И только потом регистрируем маршруты
// Health check (не требует аутентификации, поэтому должен быть выше AuthMiddleware)
r.Get("/health", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusOK)
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 маршрут зарегистрирован")
// Группируем API маршруты под /api/v1
r.Route("/api/v1", func(r chi.Router) {
// Регистрируем маршруты аутентификации
auth.RegisterRoutes(r, db, config.JWTSecret)
// Регистрируем маршруты аккаунтов
account.RegisterRoutes(r, db, config.JWTSecret)
})
zapLogger.Info("Настройка маршрутов завершена")
// Логируем маршруты (опционально)
routeLogger := logger.NewRouteLogger(logger.NewWrapper(zapLogger))
routeLogger.LogRoutes(r)
return r
}
// addProductionMiddleware добавляет все middleware для production
func addProductionMiddleware(r *chi.Mux, config *config.Config) {
// Базовые middleware
r.Use(ChiMiddleware.RequestID)
r.Use(ChiMiddleware.RealIP)
r.Use(ChiMiddleware.Logger)
r.Use(ChiMiddleware.Recoverer)
r.Use(ChiMiddleware.Timeout(30 * time.Second))
r.Use(ChiMiddleware.Compress(5, "gzip"))
r.Use(ChiMiddleware.StripSlashes)
// CORS
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"},
AllowCredentials: true,
MaxAge: 300,
}))
// Content-Type проверка
r.Use(ChiMiddleware.AllowContentType("application/json", "application/xml"))
// Rate limiting
if config.RateLimit.Enabled {
r.Use(ChiMiddleware.Throttle(config.RateLimit.RequestsPerSecond))
}
// Security headers
r.Use(func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-Content-Type-Options", "nosniff")
w.Header().Set("X-Frame-Options", "DENY")
w.Header().Set("X-XSS-Protection", "1; mode=block")
w.Header().Set("Referrer-Policy", "strict-origin-when-cross-origin")
if config.Environment == "production" {
w.Header().Set("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
}
next.ServeHTTP(w, r)
})
})
}