package main import ( "log" "os" "github.com/gofiber/fiber/v2" "geoip-rest/internal/geo" ) const ( defaultPort = "8080" defaultDBPath = "/data/GeoLite2-City.mmdb" ) func main() { dbPath := env("GEOIP_DB_PATH", defaultDBPath) port := env("PORT", defaultPort) resolver, err := geo.NewResolver(dbPath) if err != nil { log.Fatalf("failed to open GeoIP database: %v", err) } defer resolver.Close() app := fiber.New(fiber.Config{ DisableStartupMessage: true, }) app.Get("/", func(c *fiber.Ctx) error { return c.JSON(fiber.Map{ "service": "geoip-rest", "endpoints": []string{ "/health", "/lookup?ip=", }, }) }) app.Get("/health", func(c *fiber.Ctx) error { return c.JSON(fiber.Map{"status": "ok"}) }) app.Get("/lookup", func(c *fiber.Ctx) error { ip := c.Query("ip") if ip == "" { ip = c.IP() } location, err := resolver.Lookup(ip) if err != nil { if err == geo.ErrInvalidIP { return c.Status(fiber.StatusBadRequest).JSON(fiber.Map{ "error": "invalid ip address", }) } return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ "error": "lookup failed", }) } return c.JSON(location) }) log.Printf("starting GeoIP API on :%s using %s", port, dbPath) if err := app.Listen(":" + port); err != nil { log.Fatalf("server stopped: %v", err) } } func env(key, fallback string) string { if val := os.Getenv(key); val != "" { return val } return fallback }