package main import ( "fmt" "log" "os" "os/signal" "syscall" "fred-api/config" "fred-api/handlers" "github.com/gin-gonic/gin" "github.com/joho/godotenv" ) func main() { if err := godotenv.Load(); err != nil { log.Println("No .env file found, using default config") } cfg := config.Load() fredHandler := handlers.NewFREDHandler(cfg) gin.SetMode(gin.ReleaseMode) router := gin.Default() router.Use(func(c *gin.Context) { c.Header("Access-Control-Allow-Origin", "*") c.Header("Access-Control-Allow-Methods", "GET, POST, OPTIONS") c.Header("Access-Control-Allow-Headers", "Content-Type, Authorization") if c.Request.Method == "OPTIONS" { c.AbortWithStatus(204) return } c.Next() }) router.GET("/health", fredHandler.HealthCheck) api := router.Group("/api/v1") { api.GET("/category", fredHandler.GetCategory) api.GET("/category/children", fredHandler.GetCategoryChildren) api.GET("/category/related", fredHandler.GetCategoryRelated) api.GET("/category/series", fredHandler.GetCategorySeries) api.GET("/category/tags", fredHandler.GetCategoryTags) api.GET("/category/related_tags", fredHandler.GetCategoryRelatedTags) api.GET("/series", fredHandler.GetSeries) api.GET("/series/categories", fredHandler.GetSeriesCategories) api.GET("/series/observations", fredHandler.GetObservations) api.GET("/series/release", fredHandler.GetSeriesRelease) api.GET("/series/search", fredHandler.SearchSeries) api.GET("/series/search/tags", fredHandler.SearchSeriesTags) api.GET("/series/search/related_tags", fredHandler.SearchSeriesRelatedTags) api.GET("/series/tags", fredHandler.GetSeriesTags) api.GET("/series/updates", fredHandler.GetSeriesUpdates) api.GET("/series/vintagedates", fredHandler.GetSeriesVintageDates) api.GET("/releases", fredHandler.GetReleases) api.GET("/releases/dates", fredHandler.GetReleaseDates) api.GET("/release", fredHandler.GetRelease) api.GET("/release/dates", fredHandler.GetReleaseDates2) api.GET("/release/series", fredHandler.GetReleaseSeries) api.GET("/release/sources", fredHandler.GetReleaseSources) api.GET("/release/tags", fredHandler.GetReleaseTags) api.GET("/release/related_tags", fredHandler.GetReleaseRelatedTags) api.GET("/release/tables", fredHandler.GetReleaseTables) api.GET("/sources", fredHandler.GetSources) api.GET("/source", fredHandler.GetSource) api.GET("/source/releases", fredHandler.GetSourceReleases) api.GET("/tags", fredHandler.GetTags) api.GET("/related_tags", fredHandler.GetRelatedTags) api.GET("/tags/series", fredHandler.GetTagsSeries) } router.Static("/static", "./web/static") router.LoadHTMLGlob("web/templates/*") router.GET("/", func(c *gin.Context) { c.HTML(200, "index.html", gin.H{ "title": "FRED Economic Data Dashboard", }) }) go func() { fmt.Printf("FRED API Server starting on :%s\n", cfg.ServerPort) fmt.Printf("FRED API Base URL: %s\n", cfg.FREDBaseURL) fmt.Println("\nAvailable endpoints:") fmt.Println(" GET /health - Health check") fmt.Println(" GET / - Web Dashboard") fmt.Println(" GET /api/v1/series - Get series info") fmt.Println(" GET /api/v1/series/observations - Get observations") fmt.Println(" GET /api/v1/series/search - Search series") fmt.Println(" GET /api/v1/releases - Get all releases") fmt.Println(" GET /api/v1/releases/dates - Get release dates") fmt.Println(" GET /api/v1/release/series - Get series in release") fmt.Println(" GET /api/v1/category - Get category") fmt.Println(" GET /api/v1/sources - Get sources") fmt.Println(" GET /api/v1/tags - Get tags") fmt.Println("") fmt.Println("Examples:") fmt.Println(" curl 'http://localhost:" + cfg.ServerPort + "/api/v1/series?series_id=GNPCA'") fmt.Println(" curl 'http://localhost:" + cfg.ServerPort + "/api/v1/series/observations?series_id=GNPCA&limit=10'") fmt.Println(" curl 'http://localhost:" + cfg.ServerPort + "/api/v1/series/search?search_text=GDP'") fmt.Println("") if err := router.Run(":" + cfg.ServerPort); err != nil { log.Fatalf("Failed to start server: %v", err) } }() quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit fmt.Println("\nShutting down server...") }