feat: init project
This commit is contained in:
137
cmd/server/main.go
Normal file
137
cmd/server/main.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/gofiber/fiber/v3"
|
||||
"github.com/gofiber/fiber/v3/middleware/cors"
|
||||
"github.com/gofiber/fiber/v3/middleware/recover"
|
||||
"github.com/rogeecn/database_render/internal/config"
|
||||
"github.com/rogeecn/database_render/internal/database"
|
||||
"github.com/rogeecn/database_render/internal/handler"
|
||||
"github.com/rogeecn/database_render/internal/repository"
|
||||
"github.com/rogeecn/database_render/internal/service"
|
||||
"github.com/rogeecn/database_render/internal/template"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Initialize structured logging
|
||||
opts := &slog.HandlerOptions{
|
||||
Level: slog.LevelInfo,
|
||||
}
|
||||
logger := slog.New(slog.NewJSONHandler(os.Stdout, opts))
|
||||
slog.SetDefault(logger)
|
||||
|
||||
// Load configuration
|
||||
cfg, err := config.LoadConfig("")
|
||||
if err != nil {
|
||||
slog.Error("failed to load configuration", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Initialize database
|
||||
db, err := database.NewConnectionManager(cfg)
|
||||
if err != nil {
|
||||
slog.Error("failed to initialize database", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
defer func() {
|
||||
if err := db.Close(); err != nil {
|
||||
slog.Error("failed to close database", "error", err)
|
||||
}
|
||||
}()
|
||||
|
||||
// Initialize repository and services
|
||||
repo := repository.NewDataRepository(db, cfg)
|
||||
svc := service.NewDataService(repo, cfg)
|
||||
if err := svc.ValidateConfiguration(); err != nil {
|
||||
slog.Error("configuration validation failed", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Initialize renderer
|
||||
renderer, err := template.NewRenderer(svc, cfg)
|
||||
if err != nil {
|
||||
slog.Error("failed to initialize renderer", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Initialize handlers
|
||||
dataHandler := handler.NewDataHandler(svc)
|
||||
|
||||
// Initialize Fiber app
|
||||
app := fiber.New(fiber.Config{
|
||||
ReadTimeout: 30 * time.Second,
|
||||
WriteTimeout: 30 * time.Second,
|
||||
IdleTimeout: 60 * time.Second,
|
||||
ErrorHandler: renderer.ErrorHandler,
|
||||
Views: nil, // Using custom renderer
|
||||
})
|
||||
|
||||
// Setup middleware
|
||||
app.Use(recover.New())
|
||||
app.Use(cors.New(cors.Config{
|
||||
AllowOrigins: []string{"*"},
|
||||
AllowMethods: []string{"GET", "POST", "PUT", "DELETE", "OPTIONS"},
|
||||
AllowHeaders: []string{"Origin", "Content-Type", "Accept"},
|
||||
}))
|
||||
|
||||
// Setup routes
|
||||
// API routes
|
||||
dataHandler.SetupRoutes(app)
|
||||
|
||||
// Template routes
|
||||
app.Get("/", func(c fiber.Ctx) error {
|
||||
tableName := c.Query("table")
|
||||
if tableName == "" {
|
||||
return renderer.RenderIndex(c)
|
||||
}
|
||||
return renderer.RenderList(c, tableName)
|
||||
})
|
||||
|
||||
// Setup static file serving
|
||||
renderer.ServeStatic(app)
|
||||
|
||||
// Health check endpoint
|
||||
app.Get("/health", func(c fiber.Ctx) error {
|
||||
return c.JSON(map[string]string{
|
||||
"status": "ok",
|
||||
"timestamp": time.Now().Format(time.RFC3339),
|
||||
})
|
||||
})
|
||||
|
||||
// Start server
|
||||
port := cfg.App.Port
|
||||
if port == 0 {
|
||||
port = 8080
|
||||
}
|
||||
|
||||
// Start server in a goroutine
|
||||
go func() {
|
||||
slog.Info("starting server", "port", port)
|
||||
if err := app.Listen(fmt.Sprintf(":%d", port)); err != nil {
|
||||
slog.Error("server error", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}()
|
||||
|
||||
// Wait for interrupt signal to gracefully shutdown the server
|
||||
quit := make(chan os.Signal, 1)
|
||||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-quit
|
||||
|
||||
slog.Info("shutting down server...")
|
||||
|
||||
// Shutdown server
|
||||
if err := app.Shutdown(); err != nil {
|
||||
slog.Error("server shutdown error", "error", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
slog.Info("server gracefully stopped")
|
||||
}
|
||||
Reference in New Issue
Block a user