package main import ( "log" "net/http" "github.com/gin-gonic/gin" "github.com/muyuqingfeng/iloom/gateway/internal/config" "github.com/muyuqingfeng/iloom/gateway/internal/middleware" "github.com/muyuqingfeng/iloom/gateway/internal/proxy" sharedMW "github.com/muyuqingfeng/iloom/shared/pkg/middleware" ) func main() { cfg := config.Load() r := gin.New() r.Use( sharedMW.RequestID(), sharedMW.Logger(), sharedMW.Recovery(), sharedMW.CORS(cfg.AllowOrigins), middleware.RateLimit(100), ) r.GET("/health", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{"status": "ok"}) }) v1 := r.Group("/api/v1") { // /api/v1/auth/* -> AUTH_SERVICE_URL (no auth required) v1.Any("/auth/*path", proxy.NewReverseProxy(cfg.AuthServiceURL)) // /api/v1/common/* -> AUTH_SERVICE_URL (JWT required) common := v1.Group("/common", middleware.AuthRequired(cfg.JWTSecret)) common.Any("/*path", proxy.NewReverseProxy(cfg.AuthServiceURL)) // /api/v1/purchaser/* -> PURCHASER_SERVICE_URL (JWT + role=purchaser) purchaser := v1.Group("/purchaser", middleware.AuthRequired(cfg.JWTSecret), middleware.RoleRequired("purchaser"), ) purchaser.Any("/*path", proxy.NewReverseProxy(cfg.PurchaserServiceURL)) // /api/v1/textile/* -> TEXTILE_SERVICE_URL (JWT + role=textile) textile := v1.Group("/textile", middleware.AuthRequired(cfg.JWTSecret), middleware.RoleRequired("textile"), ) textile.Any("/*path", proxy.NewReverseProxy(cfg.TextileServiceURL)) // /api/v1/washing/* -> WASHING_SERVICE_URL (JWT + role=washing) washing := v1.Group("/washing", middleware.AuthRequired(cfg.JWTSecret), middleware.RoleRequired("washing"), ) washing.Any("/*path", proxy.NewReverseProxy(cfg.WashingServiceURL)) } // WebSocket proxy — route by role r.GET("/ws/v1/purchaser", proxy.NewWSProxy(cfg.PurchaserServiceURL)) r.GET("/ws/v1/textile", proxy.NewWSProxy(cfg.TextileServiceURL)) r.GET("/ws/v1/washing", proxy.NewWSProxy(cfg.WashingServiceURL)) addr := ":" + cfg.Port log.Printf("gateway listening on %s", addr) if err := r.Run(addr); err != nil { log.Fatalf("server error: %v", err) } }