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.

Go Development Architecture Practice
Go Development Architecture Practice
Go Development Architecture Practice
How to Build a Go API Gateway with Micro Framework: Step‑by‑Step Guide

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.

API gateway diagram
API gateway diagram

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=:8080

2.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.

curl test result
curl test result

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.

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.

microservicesRPCGoAPI gatewayetcdMicro
Go Development Architecture Practice
Written by

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!

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.