package main import ( "context" "embed" "errors" "github.com/gin-gonic/gin" "log" "net/http" "os" "strconv" ) //go:embed migrations/*.sql var migrations embed.FS var db *Db type ServerConfig struct { Datasource string Port string Started chan bool } func getUsers(c *gin.Context) { users, err := db.GetUsers() if err != nil { log.Printf("Error getting users: %v", err) c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal Server Error"}) return } c.IndentedJSON(http.StatusOK, users) } func getUser(c *gin.Context) { userIdStr := c.Param("userId") userId, err := strconv.Atoi(userIdStr) if err != nil { log.Printf("Invalid user ID: %v", err) c.JSON(http.StatusBadRequest, gin.H{"error": "Invalid user ID"}) return } user, err := db.GetUser(userId) if err != nil { log.Printf("Error getting user: %v", err) c.JSON(http.StatusInternalServerError, gin.H{"error": "Internal Server Error"}) return } if user == nil { c.JSON(http.StatusNotFound, gin.H{"error": "User not found"}) return } c.IndentedJSON(http.StatusOK, user) } func start(ctx context.Context, config *ServerConfig) { db = NewDb(config.Datasource) defer db.db.MustClose() router := gin.Default() router.GET("/api/users", getUsers) router.GET("/api/user/:userId", getUser) srv := &http.Server{ Addr: ":" + config.Port, Handler: router.Handler(), } go func() { if err := srv.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { log.Fatalf("listen: %s\n", err) } }() log.Printf("Running server on port %s\n", config.Port) config.Started <- true <-ctx.Done() log.Println("Shutting down") if err := srv.Shutdown(context.Background()); err != nil { log.Fatalf("Server forced to shutdown: %v", err) } } func main() { config := ServerConfig{ Datasource: os.Getenv("DB_PATH"), } start(context.Background(), &config) }