🦉
Programming Notes
  • My Programming Notes
  • CKA Exam Preparation
    • Certified Kubernetes Administrator
    • Setup Minikube
    • Network Design Principles
    • Role-Based Access Control (RBAC)
    • Namespace
    • Resource Quota
    • Pod
    • Deployment
    • Deployment: Rollout
    • ConfigMap
    • Service
    • Service: kubectl expose
    • Pod: Resources Management
    • Pod & Container: Quality of Service Class
    • Pod & Container: Probes
    • Limit Range
    • Scaling: Manual
    • Scaling: Horizontal Pod Autoscaler
    • Persistent Volume & Claim
    • Secret
    • Ingress: Routing
    • Ingress: TLS
    • Ingress: Rate Limit
    • Ingress: Basic Auth
    • Ingress: CRD (Custom Resource Definition)
    • Job
    • CronJob
    • Mutli-Node Cluster
  • Golang
    • Generics
    • Context
    • Goroutines and Channels in Go
    • Goroutine: Concurrency vs Parallelism
    • Goroutine: Performance & Tradeoffs
    • JSON: omitzero
  • Rust
    • Arrays & Slices
    • Closures
    • Generics & Traits
    • Iterators
    • Run Code Simultaneously
    • String vs &str
    • Tests
    • Rustlings Exercises
      • Variables
      • Functions
      • If
      • Primitive Types
      • Vectors
      • Move Semantics
      • Structs
      • Enums and Matching Pattern
      • Strings
      • Modules
      • Hashmaps
      • Options
      • Error Handling
      • Generics
      • Traits
      • Lifetimes
      • Tests
      • Iterators
      • Smart Pointers
      • Threads
      • Macros
      • Quiz 1
      • Quiz 2
      • Quiz 3
  • Software Engineering
    • CAP Theorem
    • Circuit Breaker
    • Decoupling
    • GraphQL: Query Caching
    • HMAC Signature
    • Idempotency
    • Monolith VS Microservice
    • OWASP Top 10 2021
    • PCI DSS
    • PostgreSQL: Partitioning
    • PostgreSQL: Replication
    • Protobuf & gRPC
    • Redis: Streams
    • Resource Scaling
    • Signed URL
    • SOLID
    • Stack VS Heap
    • Stateful VS Stateless
  • Site Reliability Engineering
    • Chaos Engineering
    • Distributed Tracing
    • Kubernetes (k8s)
    • SLA, SLO, and SLI Metrics
    • Site Reliability Engineer
  • Others
    • FFMPEG Cheat sheet
Powered by GitBook
On this page
  • Protobuf
  • gRPC
  • Example
  • Define the Protobuf File
  • Generate Code
  • Implement the Client
  • Run the System
  • Output
  1. Software Engineering

Protobuf & gRPC

Protobuf

Protobuf (Protocol Buffers) is a language-neutral, platform-neutral data serialization format developed by Google. It’s designed for efficient communication and storage, especially in distributed systems.

  • Compact and Efficient: Protobuf uses binary serialization, which is smaller and faster than formats like JSON or XML.

  • Schema-based: Data is defined in .proto files using a schema, which ensures strict typing and compatibility. Less ambiguous and easier to use programmatically.

  • Cross-language: Supported in many languages like Go, Python, Java, etc.

gRPC

(Google Remote Procedure Calls) is a high-performance RPC framework that uses Protobuf for data serialization. It enables seamless communication between services, regardless of the programming language.

  • Supports Multiple Communication Types:

    • Unary (one request, one response)

    • Server-streaming (one request, multiple responses)

    • Client-streaming (multiple requests, one response)

    • Bi-directional streaming (multiple requests, multiple responses)

  • Built-in Code Generation: gRPC generates client and server stubs automatically from the .proto file.

  • HTTP/2 Support: Enables multiplexing, compression, and improved performance over HTTP/1.1.

Example

Define the Protobuf File

user.proto

syntax = "proto3";

package user;

service UserService {
  // Unary RPC: Request user details
  rpc GetUser(GetUserRequest) returns (GetUserResponse);
}

message GetUserRequest {
  string id = 1; // User ID
}

message GetUserResponse {
  string id = 1;
  string name = 2;
  int32 age = 3;
}

Generate Code

Run the following command to generate the code (example for Go):

protoc --go_out=. --go-grpc_out=. user.proto

This generates:

  1. user.pb.go: Contains Protobuf message definitions.

  2. user_grpc.pb.go: Contains gRPC service definitions (interfaces for server and client).

Step 3: Implement the Server

server.go

package main

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "path/to/generated/user" // Update with actual path
)

// Server struct implements the generated UserServiceServer interface
type Server struct {
    pb.UnimplementedUserServiceServer
}

// Implement GetUser method
func (s *Server) GetUser(ctx context.Context, req *pb.GetUserRequest) (*pb.GetUserResponse, error) {
    log.Printf("Received request for user ID: %s", req.Id)

    // Mock user data
    user := &pb.GetUserResponse{
        Id:   req.Id,
        Name: "John Doe",
        Age:  30,
    }
    return user, nil
}

func main() {
    listener, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("Failed to listen: %v", err)
    }

    grpcServer := grpc.NewServer()
    pb.RegisterUserServiceServer(grpcServer, &Server{})

    log.Println("Server is running on port 50051")
    if err := grpcServer.Serve(listener); err != nil {
        log.Fatalf("Failed to serve: %v", err)
    }
}

Implement the Client

client.go

package main

import (
    "context"
    "log"
    "time"

    "google.golang.org/grpc"
    pb "path/to/generated/user" // Update with actual path
)

func main() {
    conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("Failed to connect to server: %v", err)
    }
    defer conn.Close()

    client := pb.NewUserServiceClient(conn)

    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()

    // Call GetUser RPC
    req := &pb.GetUserRequest{Id: "123"}
    resp, err := client.GetUser(ctx, req)
    if err != nil {
        log.Fatalf("Error calling GetUser: %v", err)
    }

    log.Printf("User details: ID=%s, Name=%s, Age=%d", resp.Id, resp.Name, resp.Age)
}

Run the System

Start the gRPC server:

go run server.go

Run the client:

go run client.go

Output

On the server:

Received request for user ID: 123

On the client:

User details: ID=123, Name=John Doe, Age=30
PreviousPostgreSQL: ReplicationNextRedis: Streams

Last updated 4 months ago