Microservices Communication Patterns: REST vs gRPC vs Message Broker

3 min read
#microservices #grpc #rest #rabbitmq #architecture

Dalam membangun microservices, memilih communication pattern yang tepat sangat krusial. Di artikel ini, saya akan share pengalaman menggunakan berbagai patterns di production.

1. REST API (Synchronous)

Kapan Digunakan?

  • Communication antar services yang membutuhkan response langsung
  • Public-facing APIs
  • Simple CRUD operations

Contoh Implementation

// User Service
func GetUserHandler(w http.ResponseWriter, r *http.Request) {
    userID := mux.Vars(r)["id"]
    user, err := userService.GetByID(userID)

    if err != nil {
        http.Error(w, err.Error(), http.StatusNotFound)
        return
    }

    json.NewEncoder(w).Encode(user)
}

Kelebihan

✅ Simple & familiar ✅ Human-readable ✅ Good tooling support ✅ Easy debugging

Kekurangan

❌ Verbose payloads ❌ No type safety ❌ Slower than binary protocols

2. gRPC (Synchronous)

Kapan Digunakan?

  • Internal service-to-service communication
  • High-performance requirements
  • Strong typing needed
  • Streaming data

Contoh Implementation

// user.proto
syntax = "proto3";

service UserService {
  rpc GetUser(GetUserRequest) returns (User);
  rpc StreamUsers(Empty) returns (stream User);
}

message User {
  int64 id = 1;
  string name = 2;
  string email = 3;
}
// Server implementation
func (s *server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.User, error) {
    user, err := s.userRepo.FindByID(req.Id)
    if err != nil {
        return nil, status.Error(codes.NotFound, "user not found")
    }

    return &pb.User{
        Id:    user.ID,
        Name:  user.Name,
        Email: user.Email,
    }, nil
}

Kelebihan

✅ High performance (binary protocol) ✅ Type safety with protobuf ✅ Built-in streaming ✅ Auto-generated client code

Kekurangan

❌ Steeper learning curve ❌ Less human-readable ❌ Browser support requires proxy

3. Message Broker (Asynchronous)

Kapan Digunakan?

  • Event-driven architecture
  • Tasks yang bisa diproses async
  • Decoupling services
  • Need for reliability & retry

Contoh dengan RabbitMQ

// Publisher
func PublishOrderCreated(order Order) error {
    body, _ := json.Marshal(order)

    err := channel.Publish(
        "orders",           // exchange
        "order.created",    // routing key
        false,              // mandatory
        false,              // immediate
        amqp.Publishing{
            ContentType: "application/json",
            Body:        body,
        },
    )

    return err
}

// Consumer
func ConsumeOrders() {
    msgs, _ := channel.Consume(
        "order-queue",
        "",
        false,  // auto-ack
        false,
        false,
        false,
        nil,
    )

    for msg := range msgs {
        var order Order
        json.Unmarshal(msg.Body, &order)

        if err := processOrder(order); err != nil {
            msg.Nack(false, true)  // requeue
            continue
        }

        msg.Ack(false)
    }
}

Kelebihan

✅ Loose coupling ✅ Better fault tolerance ✅ Load leveling ✅ Built-in retry & DLQ

Kekurangan

❌ Eventual consistency ❌ More complex debugging ❌ Additional infrastructure

Real-World Use Case

Di project Xetia.io, saya menggunakan kombinasi ketiganya:

REST API:

  • Public APIs untuk mobile/web client
  • Admin dashboard

gRPC:

  • Communication antara Order Service → Inventory Service
  • Real-time data sync between services

RabbitMQ:

  • Order processing pipeline
  • Email/notification dispatch
  • Delivery status updates

Pattern Decision Matrix

KriteriaRESTgRPCMessage Broker
Speed⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Simplicity⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Reliability⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐
Type Safety⭐⭐⭐⭐⭐⭐⭐⭐⭐
Debugging⭐⭐⭐⭐⭐⭐⭐⭐⭐⭐

Kesimpulan

Tidak ada “best” pattern - semuanya tergantung use case Anda:

  • REST: Default choice untuk simplicity
  • gRPC: Ketika performance & type safety penting
  • Message Broker: Untuk async processing & loose coupling

Kombinasi ketiganya seringkali menjadi solusi terbaik untuk system yang kompleks.

Yang penting: measure, monitor, and adapt berdasarkan kebutuhan actual Anda! 📊

Share this article

AS

Arian Saputra

Backend Engineer with 6+ years across BPM & distributed systems. Go, microservices, CI/CD, performance tuning.