100 lines
3.2 KiB
Go
100 lines
3.2 KiB
Go
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
|
|
// Public auth endpoints (no JWT required)
|
|
authPublic := v1.Group("/auth")
|
|
authPublic.POST("/register", proxy.NewReverseProxy(cfg.AuthServiceURL))
|
|
authPublic.POST("/login", proxy.NewReverseProxy(cfg.AuthServiceURL))
|
|
authPublic.POST("/logout", proxy.NewReverseProxy(cfg.AuthServiceURL))
|
|
authPublic.POST("/refresh", proxy.NewReverseProxy(cfg.AuthServiceURL))
|
|
|
|
// Protected auth endpoints (JWT required to set X-User-ID)
|
|
authProtected := v1.Group("/auth", middleware.AuthRequired(cfg.JWTSecret))
|
|
authProtected.GET("/me", 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))
|
|
|
|
// /api/v1/muyu/* -> MUYU_GATEWAY_URL (muyu warehouse subsystem)
|
|
// muyu-gateway handles its own authentication internally
|
|
muyu := v1.Group("/muyu",
|
|
middleware.AuthRequired(cfg.JWTSecret),
|
|
)
|
|
muyu.Any("/*path", proxy.NewReverseProxy(cfg.MuyuGatewayURL))
|
|
}
|
|
|
|
// WebSocket proxy — route by role (JWT + role check applied)
|
|
r.GET("/ws/v1/purchaser",
|
|
middleware.AuthRequired(cfg.JWTSecret),
|
|
middleware.RoleRequired("purchaser"),
|
|
proxy.NewWSProxy(cfg.PurchaserServiceURL, cfg.AllowOrigins),
|
|
)
|
|
r.GET("/ws/v1/textile",
|
|
middleware.AuthRequired(cfg.JWTSecret),
|
|
middleware.RoleRequired("textile"),
|
|
proxy.NewWSProxy(cfg.TextileServiceURL, cfg.AllowOrigins),
|
|
)
|
|
r.GET("/ws/v1/washing",
|
|
middleware.AuthRequired(cfg.JWTSecret),
|
|
middleware.RoleRequired("washing"),
|
|
proxy.NewWSProxy(cfg.WashingServiceURL, cfg.AllowOrigins),
|
|
)
|
|
|
|
addr := ":" + cfg.Port
|
|
log.Printf("gateway listening on %s", addr)
|
|
if err := r.Run(addr); err != nil {
|
|
log.Fatalf("server error: %v", err)
|
|
}
|
|
}
|