veza/veza-backend-api/cmd/simple_main.go

144 lines
3.1 KiB
Go
Raw Normal View History

2025-12-03 19:29:37 +00:00
package main
import (
"context"
"log"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/gin-gonic/gin"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
)
func main() {
// Initialiser le logger
logger, err := zap.NewProduction()
if err != nil {
log.Fatalf("Failed to initialize logger: %v", err)
}
defer logger.Sync()
// Initialiser Redis
redisClient, err := initRedis("redis://localhost:6379")
if err != nil {
logger.Error("Failed to initialize Redis", zap.Error(err))
// Continuer sans Redis pour les tests
redisClient = nil
}
// Configurer Gin
if os.Getenv("GIN_MODE") == "release" {
gin.SetMode(gin.ReleaseMode)
}
// Créer le router
router := gin.New()
// Middleware de logging
router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
logger.Info("HTTP Request",
zap.String("method", param.Method),
zap.String("path", param.Path),
zap.Int("status", param.StatusCode),
zap.Duration("latency", param.Latency),
zap.String("client_ip", param.ClientIP),
)
return ""
}))
// Middleware de récupération d'erreurs
router.Use(gin.Recovery())
// Middleware CORS
router.Use(func(c *gin.Context) {
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS")
c.Header("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization")
c.Header("Access-Control-Max-Age", "86400")
if c.Request.Method == "OPTIONS" {
c.AbortWithStatus(204)
return
}
c.Next()
})
// Routes de test
router.GET("/health", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"status": "ok",
"timestamp": time.Now(),
})
})
router.GET("/test", func(c *gin.Context) {
c.JSON(http.StatusOK, gin.H{
"message": "Test endpoint",
"redis_connected": redisClient != nil,
})
})
// Configuration du serveur
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
server := &http.Server{
Addr: ":" + port,
Handler: router,
ReadTimeout: 15 * time.Second,
WriteTimeout: 15 * time.Second,
IdleTimeout: 60 * time.Second,
}
// Démarrer le serveur en arrière-plan
go func() {
logger.Info("Starting server", zap.String("port", port))
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
logger.Fatal("Failed to start server", zap.Error(err))
}
}()
// Attendre un signal d'arrêt
quit := make(chan os.Signal, 1)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
logger.Info("Shutting down server...")
// Arrêter le serveur gracieusement
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
defer cancel()
if err := server.Shutdown(ctx); err != nil {
logger.Fatal("Server forced to shutdown", zap.Error(err))
}
logger.Info("Server exited")
}
// initRedis initialise la connexion Redis
func initRedis(redisURL string) (*redis.Client, error) {
opts, err := redis.ParseURL(redisURL)
if err != nil {
return nil, err
}
client := redis.NewClient(opts)
// Test de connexion
ctx := context.Background()
_, err = client.Ping(ctx).Result()
if err != nil {
return nil, err
}
return client, nil
}