How to Build a Go API Gateway with Micro Framework: Step‑by‑Step Guide
This article explains the role of an API gateway in microservice architectures, walks through configuring the micro framework’s gateway with options like address, namespace and handler, shows how to modify server and client code, and demonstrates testing the gateway using curl.
1. What Is an API Gateway
When an application is split into multiple microservices, clients (iOS, Android, web) must call many different URLs. An API gateway provides a single entry point, handling protocol conversion and routing requests to backend services. It also offers security, rate‑limiting, and circuit‑breaker features; large companies often build their own gateways (e.g., Tencent TGW).
The micro framework includes an HTTP‑based gateway. Requests sent to the gateway are forwarded to the appropriate backend service, and the gateway supports ACME and TLS for security.
2. Adding Gateway Support
We now extend the example program with a gateway.
2.1 Start the Gateway
Run micro api --help to see the available options: --address: gateway listening address (default 8080) --namespace: logical grouping of services (e.g., com.test.api) --handler: type of HTTP handler (api, rpc, event, proxy). We use the rpc handler for this demo.
Start the gateway with environment variables for the registry:
MICRO_REGISTRY=etcd
MICRO_REGISTRY_ADDRESS=127.0.0.1:2379
micro api --handler=rpc --namespace=com.jupiter.api --address=:80802.2 Modify the Code
Update the server to use a new service name svr.greeter:
package main
import (
"context"
"fmt"
"github.com/micro/go-micro/v2"
"micro/proto/pb"
"micro/registry/etcd"
)
type Greeter struct {}
func (g *Greeter) Hello(ctx context.Context, req *pb.Request, rsp *pb.Response) error {
// Echo the request back to the client
rsp.Msg = req.Name
return nil
}
func main() {
service := micro.NewService(
micro.Name("svr.greeter"),
micro.Registry(etcd.NewRegistry()),
)
service.Init()
pb.RegisterGreeterHandler(service.Server(), new(Greeter))
if err := service.Run(); err != nil {
fmt.Println(err)
}
}Create a client that acts as a proxy (the gateway handler). It implements the same interface as the server and forwards calls via RPC:
package main
import (
"context"
"fmt"
"github.com/micro/go-micro/v2"
"micro/proto/pb"
"micro/registry/etcd"
)
const (
apiNameSpace = "com.jupiter.api"
service = "greeter"
backendService = "svr.greeter" // actual backend service
)
type Greeter struct {
Client pb.GreeterService
}
func (g *Greeter) Hello(ctx context.Context, req *pb.Request, rsp *pb.Response) error {
// Forward the request to the backend via RPC
response, e := g.Client.Hello(ctx, &pb.Request{Name: "Hello Micro"})
if e != nil {
return e
}
rsp.Msg = response.Msg
return nil
}
func main() {
service := micro.NewService(
micro.Name(apiNameSpace+"."+service), // namespace.service
micro.Registry(etcd.NewRegistry()),
)
service.Init()
pb.RegisterGreeterHandler(service.Server(), &Greeter{
Client: pb.NewGreeterService(backendService, service.Client()),
})
if err := service.Run(); err != nil {
fmt.Println(err)
}
}The corresponding .proto definition is:
service Greeter {
rpc Hello (Request) returns (Response) {}
}2.3 Test the Gateway
After starting both the backend service and the gateway, issue a curl request to the gateway endpoint: curl http://localhost:8080/greeter/hello The response contains the expected message, confirming that the gateway correctly forwards the request.
3. Summary
By extending the original microservice example with an API gateway, we now have a unified entry point that handles routing, security, and protocol conversion. The small demo shows how to configure the gateway, modify service names to match the required namespace.service pattern, and verify end‑to‑end functionality with a simple curl test.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Go Development Architecture Practice
Daily sharing of Golang-related technical articles, practical resources, language news, tutorials, real-world projects, and more. Looking forward to growing together. Let's go!
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
