// Package gateway provides an HTTP gateway for micro run package gateway import ( "context" "encoding/json" "fmt" "io" "net/http" "strings" "sync" "time" "go-micro.dev/v5/client" "go-micro.dev/v5/codec/bytes" "go-micro.dev/v5/health" "go-micro.dev/v5/registry" ) // Gateway provides HTTP access to micro services type Gateway struct { addr string server *http.Server services []ServiceInfo mu sync.RWMutex } // ServiceInfo holds information about a running service type ServiceInfo struct { Name string `json:"name"` Address string `json:"address"` Port int `json:"port,omitempty"` } // New creates a new gateway func New(addr string) *Gateway { return &Gateway{ addr: addr, } } // SetServices updates the list of known services func (g *Gateway) SetServices(services []ServiceInfo) { g.mu.Lock() g.services = services g.mu.Unlock() } // Start starts the gateway HTTP server func (g *Gateway) Start() error { mux := http.NewServeMux() // Health endpoint - aggregates all service health mux.HandleFunc("/health", g.healthHandler) mux.HandleFunc("/health/live", g.liveHandler) mux.HandleFunc("/health/ready", g.readyHandler) // API endpoint - HTTP to RPC proxy mux.HandleFunc("/api/", g.apiHandler) // Services list mux.HandleFunc("/services", g.servicesHandler) // Home page mux.HandleFunc("/", g.homeHandler) g.server = &http.Server{ Addr: g.addr, Handler: mux, } go func() { if err := g.server.ListenAndServe(); err != nil && err != http.ErrServerClosed { fmt.Printf("Gateway error: %v\n", err) } }() return nil } // Stop stops the gateway func (g *Gateway) Stop() { if g.server != nil { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() g.server.Shutdown(ctx) } } // Addr returns the gateway address func (g *Gateway) Addr() string { return g.addr } func (g *Gateway) homeHandler(w http.ResponseWriter, r *http.Request) { if r.URL.Path != "/" { http.NotFound(w, r) return } g.mu.RLock() services := g.services g.mu.RUnlock() // Get services from registry regServices, _ := registry.ListServices() w.Header().Set("Content-Type", "text/html; charset=utf-8") fmt.Fprintf(w, `
Services are running
No services registered yet...
`) } fmt.Fprintf(w, `curl -X POST http://localhost%s/api/{service}/{Endpoint} -d '{}'