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.
63 lines
1.3 KiB
Go
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)
|
|
}
|
|
}
|