Build a Lego‑Style Go Microservice Gateway with Consul, Gin, and Go‑Kit

This guide walks you through building a Go microservice gateway using Consul for service discovery, Gin for routing, and Go‑Kit middleware, covering project structure, configuration loading, middleware composition, dynamic routing, common pitfalls, startup commands, and extensible features.

Code Wrench
Code Wrench
Code Wrench
Build a Lego‑Style Go Microservice Gateway with Consul, Gin, and Go‑Kit

Project Structure

├── middleware/        # circuit‑breaker & rate‑limiting middleware
├── pkg/config/        # Consul configuration center
├── pkg/logger/        # logging system
├── test/              # sample microservice
├── main.go            # gateway entry point

Core Features (Four Steps)

Step 1: Load Configuration

// main.go initialization
config.LoadServiceConfig("gateway", "prod") // load service‑specific config first
appConfig := config.GetAppConfig()
logger.Init("gateway", appConfig) // start logging system

The gateway reads its own configuration from Consul before starting the logger.

Step 2: Service Discovery (Consul)

Consul acts as the service registry; the gateway queries Consul to discover healthy instances of downstream services.

Step 3: Middleware Composition

// circuit‑breaker + rate‑limiter combo
cb := circuitbreaker.NewHystrix("server1") // instantiate breaker
limiter := rate.NewLimiter(rate.Every(time.Second*10), 5) // 5 requests per 10 s

r.Use(
    middleware.RateLimitMiddleware(limiter), // rate‑limit
    middleware.CircuitBreakerMiddleware(cb), // circuit‑breaker
    middleware.AuthMiddleware(jwtKey), // authentication
)

Step 4: Dynamic Routing

// dynamic route handling
r.Any("/api/:service/*action", func(c *gin.Context) {
    service := c.Param("service")
    balancer, ok := balancers[service]
    if !ok {
        c.JSON(502, gin.H{"error": "service not found"})
        return
    }
    endpoint, err := balancer.Endpoint()
    if err != nil {
        c.JSON(502, gin.H{"error": err.Error()})
        return
    }
    _, err = endpoint(c, nil)
    if err != nil {
        c.JSON(502, gin.H{"error": err.Error()})
    }
})

The gateway extracts the target service from the URL, obtains a load‑balanced endpoint via Consul, forwards the request, and returns graceful errors when the service is unavailable.

Pitfall Avoidance

Consul registration essentials : IP, port, and health‑check URL must exactly match the configuration file; otherwise the service will disappear from discovery.

Gin context propagation :

// propagate key fields from Gin context
func proxyFactory(instance string) endpoint.Endpoint {
    return func(ctx context.Context, req interface{}) (interface{}, error) {
        ginCtx, _ := ctx.(*gin.Context)
        action := ginCtx.Param("action") // forward route param
        // ...additional propagation logic
        return nil, nil
    }
}

Start the Gateway

# Start Consul and auxiliary services
docker run -d --name consul -p 8500:8500 consul:latest
docker-compose -f deploy/docker/docker-compose.yaml up -d loki

# Build and run the gateway
go build -o gateway main.go
CONFIG_ENV=dev ./gateway

Visit http://localhost:10001/api/server1/hello to see the request forwarded to the downstream service; circuit‑breaker returns a graceful error on failure, and rate‑limiting returns HTTP 429 when the limit is exceeded.

Extending the Gateway

Canary releases : add version tags to routing rules for staged rollouts.

Tracing : integrate OpenTelemetry to record call chains.

Dynamic configuration : use Consul watch to reload configuration without restarting.

Multi‑protocol support : extend to translate gRPC calls to HTTP.

Repository

GitHub: https://github.com/louis-xie-programmer/easyms.golang

Gitee: https://gitee.com/louis_xie/easyms.golang

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

middlewareConsulGinGo-Kit
Code Wrench
Written by

Code Wrench

Focuses on code debugging, performance optimization, and real-world engineering, sharing efficient development tips and pitfall guides. We break down technical challenges in a down-to-earth style, helping you craft handy tools so every line of code becomes a problem‑solving weapon. 🔧💻

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.