Files
api-golang/main.go
Flavio Fois 84521d8d59 refactor routing into a modular and versioned structure
Move inline route definitions from main.go into a dedicated internal/routes package. This organization introduces support for API versioning (v1) and separates endpoint logic into specialized modules for administration and bug reporting.
2026-03-23 09:18:16 +01:00

63 lines
1.3 KiB
Go

package main
import (
"fmt"
"log"
"net/http"
"time"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"github.com/go-chi/httprate"
"github.com/jmoiron/sqlx"
"github.com/joho/godotenv"
"emly-api-go/internal/config"
"emly-api-go/internal/database"
"emly-api-go/internal/database/schema"
"emly-api-go/internal/routes"
)
func main() {
// Load .env (ignored if not present in production)
_ = godotenv.Load()
cfg := config.Load()
db, err := database.Connect(cfg)
if err != nil {
log.Fatalf("database connection failed: %v", err)
}
defer func(db *sqlx.DB) {
err := db.Close()
if err != nil {
log.Fatalf("closing database failed: %v", err)
}
}(db)
// Run conditional schema migrations
if err := schema.Migrate(db, cfg.Database); err != nil {
log.Fatalf("schema migration failed: %v", err)
}
r := chi.NewRouter()
// Global middlewares
r.Use(middleware.RequestID)
r.Use(middleware.RealIP)
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
r.Use(middleware.Timeout(30 * time.Second))
// Global rate limit to 100 requests per minute
r.Use(httprate.LimitByIP(100, time.Minute))
routes.RegisterAll(r, db)
addr := fmt.Sprintf(":%s", cfg.Port)
log.Printf("server listening on %s", addr)
if err := http.ListenAndServe(addr, r); err != nil {
log.Fatalf("server error: %v", err)
}
}