Adr 010 Unified Gateway
Authors: Go Micro Team
Status: Accepted Date: 2026-02-11 Authors: Go Micro Team
Context
Previously, the go-micro CLI had two separate gateway implementations:
micro rungateway (cmd/micro/run/gateway/) - Simple HTTP-to-RPC proxy for developmentmicro servergateway (cmd/micro/server/) - Production gateway with authentication, web UI, and API documentation
This duplication created several problems:
- Code maintenance: Gateway logic (HTTP-to-RPC translation, service discovery, health checks) was implemented twice
- Feature parity: Improvements to one gateway didn’t automatically benefit the other
- Complexity: New features (like MCP integration) would need to be implemented twice
- Testing burden: Each gateway required separate testing
Decision
We unified the gateway implementation by:
Extracting reusable gateway module (
cmd/micro/server/gateway.go):GatewayOptionsstruct for configurationStartGateway()function that returns a*GatewayimmediatelyRunGateway()function that blocks until shutdown- Configurable authentication (enabled/disabled)
Refactoring
micro server:- Gateway logic remains in
cmd/micro/server/ registerHandlers()now uses instance-specific*http.ServeMuxinstead of global mux- Authentication middleware is conditional based on
GatewayOptions.AuthEnabled - Auth routes only register when authentication is enabled
- Gateway logic remains in
Updating
micro run:- Removed duplicate gateway implementation (
cmd/micro/run/gateway/) - Now calls
server.StartGateway()withAuthEnabled: true - Retains process management and hot reload functionality
- Same auth, scopes, and token management as
micro server
- Removed duplicate gateway implementation (
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Unified Gateway │
│ (cmd/micro/server/gateway.go) │
│ │
│ • HTTP → RPC translation │
│ • Service discovery via registry │
│ • Web UI (dashboard, logs, API docs) │
│ • Health checks │
│ • Configurable authentication │
│ • Endpoint scopes for access control │
│ • MCP tool integration with scope enforcement │
└─────────────────────────────────────────────────────────────┘
▲ ▲
│ │
┌──────┴──────┐ ┌────────┴────────┐
│ micro run │ │ micro server │
│ │ │ │
│ + Process │ │ + Auth enabled │
│ mgmt │ │ + JWT tokens │
│ + Hot │ │ + Scopes │
│ reload │ │ + Production │
│ + Auth │ │ │
│ + Scopes │ │ │
└─────────────┘ └─────────────────┘
Usage
Development Mode (micro run)
# Start services with gateway (auth enabled, default admin/micro)
micro run
# Gateway provides:
# - HTTP API at /api/{service}/{endpoint}
# - Web dashboard at /
# - JWT authentication (admin/micro default)
# - Endpoint scopes at /auth/scopes
Production Mode (micro server)
# Start gateway with authentication
micro server --address :8080
# Gateway provides:
# - HTTP API at /api/{service}/{endpoint} (auth required)
# - Web dashboard with login
# - JWT-based authentication
# - User/token management UI
# - Endpoint scopes at /auth/scopes
Benefits
- Single Source of Truth: Gateway logic lives in one place
- Automatic Feature Propagation: New features (like MCP) added to the unified gateway benefit both commands
- Simplified Testing: Test gateway once, works everywhere
- Reduced Code Size: Eliminated ~300 lines of duplicate code
- Clear Separation:
micro server= API gateway (HTTP + future MCP)micro run= Development tool (gateway + process management + hot reload)
Implementation Details
GatewayOptions
type GatewayOptions struct {
Address string // Listen address (e.g., ":8080")
AuthEnabled bool // Enable JWT authentication
Store store.Store // Storage for auth data
Context context.Context // Cancellation context
}
Starting the Gateway
// Non-blocking start
gw, err := server.StartGateway(server.GatewayOptions{
Address: ":8080",
AuthEnabled: false,
})
// Blocking start
err := server.RunGateway(server.GatewayOptions{
Address: ":8080",
AuthEnabled: true,
})
Authentication
When AuthEnabled: true:
- Auth middleware checks JWT tokens on all requests
- Auth routes are registered:
/auth/login,/auth/logout,/auth/tokens,/auth/users - Web UI requires login
- API endpoints require
Authorization: Bearer <token>header
When AuthEnabled: false (dev mode):
- No authentication middleware
- Auth routes are not registered
- All endpoints are publicly accessible
Consequences
Positive
- Easier to add new features (only implement once)
- Better code maintainability
- Consistent behavior between development and production
- Foundation for MCP integration
Negative
cmd/micro/runnow depends oncmd/micro/server(acceptable for CLI tools)- Slightly more complex initialization in
micro run(but cleaner overall)
Future Work
With unified gateway architecture, we can now add:
- MCP Integration: Add
mcp.goto server package, both commands get MCP support - GraphQL API: Single implementation serves both dev and prod
- gRPC Gateway: Expose services via gRPC alongside HTTP
- API Versioning: Consistent versioning strategy across all deployments
References
- Original issue: Gateway duplication between
micro runandmicro server - Implementation: PR #XXX (gateway unification)
- Related: ADR-001 (Plugin Architecture), ADR-009 (Progressive Configuration)
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.