Skip to content
Santekno.com | Tech Tutorials and Trends
EN
📖 0%
18 Aug 2025 · 6 min read ·Article 71 / 110
Go

71. Integrating gRPC with a REST Gateway (grpc-gateway)

IH
Ihsan Arif
Writer at Santekno · Backend Engineer

71. Integrating gRPC with a REST Gateway (grpc-gateway)

In modern API development, two architectures often spark heated debate: REST and gRPC. REST (Representational State Transfer) has long been the default standard for frontend-backend communication over HTTP, while gRPC (Google Remote Procedure Call) is known for its performance, efficiency, and ease of connecting services between servers, especially in large-scale microservice systems.

In many organizations, however, there is usually a need to provide a public REST-based API while keeping internal service-to-service communication more optimal using gRPC. Translating between REST and gRPC manually is clearly inefficient and adds maintenance overhead to the codebase. This is where grpc-gateway comes in as an automated solution.

In this article, I’ll cover the integration of gRPC with a REST Gateway using grpc-gateway, complete with code examples, flow diagrams, and a request-response simulation. Let’s start from the theory and work our way through to the implementation!


Why Do We Need to Integrate REST and gRPC?

Before we dive into the implementation, let’s first understand why this integration matters:

NeedRESTgRPC
CompatibilitySupports web & mobileLimited to the backend
PerformanceJSON overhead, HTTP/1.1Binary, HTTP/2, efficient
API DocumentationOpenAPI/SwaggerProtobuf schema
StreamingLimitedFull streaming support
API EvolutionRelatively easyVery easy (Protobuf)

Many teams want both of these strengths without having to write two separate implementations. With grpc-gateway, we can expose the same service over both gRPC and REST/JSON, and also generate OpenAPI documentation automatically.


How Does grpc-gateway Work?

Let’s visualize the process with the following diagram:

MERMAID
graph TD;
    A[Client REST (HTTP/JSON)] -->|Request| B[grpc-gateway (Transcoder)];
    B -->|gRPC call (Protobuf)| C[gRPC Server];
    C -->|Response (Protobuf)| B;
    B -->|Response (HTTP/JSON)| A;

Explanation:

  1. The REST Client sends an HTTP request (usually JSON).
  2. grpc-gateway receives it, translates it into gRPC (Protobuf), and forwards it to the original gRPC server.
  3. The gRPC Server processes the request and returns a binary/Protobuf response.
  4. grpc-gateway translates it back into JSON and sends it to the REST client.

With this approach, you can write your business logic in one codebase yet expose two different APIs (gRPC & RESTful) automatically!


Installing and Setting Up grpc-gateway

We’ll use Go (the primary language for grpc-gateway), but the concepts are similar in other languages.

1. Install Protoc and the grpc-gateway Plugins

bash
 1# Install protoc (the protobuf compiler)
 2sudo apt install protobuf-compiler
 3
 4# Install the Go plugins for grpc, gateway, and openapiv2
 5go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
 6go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
 7go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-grpc-gateway@latest
 8go install github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2@latest
 9
10# Make sure $GOPATH/bin is on your $PATH
11export PATH="$PATH:$(go env GOPATH)/bin"

Implementation Example: A Simple User API

1. Define the Protobuf Service

File: user.proto

proto
 1syntax = "proto3";
 2
 3package user;
 4
 5option go_package = "github.com/yourorg/yourrepo/gen/user;user";
 6
 7import "google/api/annotations.proto";
 8
 9service UserService {
10    rpc GetUser(GetUserRequest) returns (UserResponse) {
11        option (google.api.http) = {
12            get: "/v1/users/{id}"
13        };
14    }
15}
16
17message GetUserRequest {
18    string id = 1;
19}
20
21message UserResponse {
22    string id = 1;
23    string name = 2;
24    string email = 3;
25}

Notice the google.api.http annotation: this is the key that lets grpc-gateway know which HTTP endpoint should be transcoded into the RPC call.


2. Generate the Code

bash
1protoc -I. \
2    -I $GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway@v2.*/third_party/googleapis \
3    --go_out=. --go_opt=paths=source_relative \
4    --go-grpc_out=. --go-grpc_opt=paths=source_relative \
5    --grpc-gateway_out=. --grpc-gateway_opt=paths=source_relative \
6    user.proto

3. Implement the gRPC Server

File: server.go

go
 1package main
 2
 3import (
 4    "context"
 5    "log"
 6    "net"
 7
 8    "google.golang.org/grpc"
 9    pb "github.com/yourorg/yourrepo/gen/user"
10)
11
12type server struct {
13    pb.UnimplementedUserServiceServer
14}
15
16func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.UserResponse, error) {
17    return &pb.UserResponse{
18        Id:    req.Id,
19        Name:  "Alice",
20        Email: "alice@example.com",
21    }, nil
22}
23
24func main() {
25    lis, err := net.Listen("tcp", ":50051")
26    if err != nil {
27        log.Fatalf("failed to listen: %v", err)
28    }
29    s := grpc.NewServer()
30    pb.RegisterUserServiceServer(s, &server{})
31    log.Println("gRPC server listening on :50051")
32    if err := s.Serve(lis); err != nil {
33        log.Fatalf("failed to serve: %v", err)
34    }
35}

4. Implement the REST Gateway

File: gateway.go

go
 1package main
 2
 3import (
 4    "context"
 5    "log"
 6    "net/http"
 7    "github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
 8    "google.golang.org/grpc"
 9    pb "github.com/yourorg/yourrepo/gen/user"
10)
11
12func main() {
13    ctx := context.Background()
14    mux := runtime.NewServeMux()
15    opts := []grpc.DialOption{grpc.WithInsecure()} // Insecure for dev
16
17    err := pb.RegisterUserServiceHandlerFromEndpoint(
18        ctx, mux, "localhost:50051", opts,
19    )
20    if err != nil {
21        log.Fatalf("Failed to register gateway: %v", err)
22    }
23
24    log.Println("REST gateway listening on :8080")
25    http.ListenAndServe(":8080", mux)
26}

5. Request Simulation: JSON to gRPC Automatically

For example, suppose we make this request:

bash
1curl http://localhost:8080/v1/users/1234

The response we’ll get back:

json
1{
2    "id": "1234",
3    "name": "Alice",
4    "email": "alice@example.com"
5}
What happens behind the scenes:

  1. The REST client (curl) sends a request to the gateway
  2. The gateway translates it into a gRPC request to port 50051
  3. The gRPC server processes it and replies with protobuf
  4. The gateway translates it into a JSON response and returns it to the client

Advantages and Limitations of grpc-gateway

Advantages:

  • No need to implement two separate services (REST & gRPC).
  • Supports paths, query parameters, and request bodies in line with OpenAPI.
  • Can generate OpenAPI specifications automatically.
  • Highly efficient when migrating a monolith to microservices or a hybrid API.

Limitations:

  • Not every gRPC feature can be exposed via HTTP/JSON (for example, bidirectional streaming isn’t 100% supported yet).
  • Adding a layer means potentially increased latency.
  • You have to maintain the annotation mapping in the Protobuf.

Case Study: Gradual Migration to gRPC

One migration pattern that is frequently used:

  • Step 1: Rewrite/migrate the business logic into a gRPC service.
  • Step 2: Provide a gRPC API for internal communication.
  • Step 3: Expose REST/JSON for external consumers (frontend, mobile) via grpc-gateway.
  • Step 4: Shut down the original REST API once consumers have migrated to the new one.

The benefit of this pattern – no breaking changes on the client side.


Conclusion

Integrating gRPC with a REST Gateway (grpc-gateway) is a solution that bridges the old world of REST and the new world of gRPC. This approach is ideal for organizations that want to modernize their APIs without sacrificing compatibility or developer productivity.

As an engineer, leveraging tools like grpc-gateway isn’t just about efficiency – it’s also about reducing technical debt and providing a seamless developer experience for teams working across different technologies.

Don’t hesitate to explore grpc-gateway further, for example with authentication, custom error handling, or automatically generating OpenAPI documentation. Happy coding, and cheers to refactoring!


References:


Related Articles

💬 Comments