> For the complete documentation index, see [llms.txt](https://www.anandisheladiya.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.anandisheladiya.com/skills-and-experience/api/rpc-remote-procedure-call.md).

# RPC (Remote Procedure Call)

### **What is RPC?**

RPC (Remote Procedure Call) is a protocol that allows a program to execute a procedure (function) on a remote server as if it were a local function. This enables distributed computing where different services interact seamlessly over a network.

Unlike REST APIs, which are resource-based, RPC focuses on calling functions or procedures directly.

### **RPC Architecture and Workflow**

#### **Architecture Components**

1. **Client** – Initiates the RPC request.
2. **Stub (Client-Side Proxy)** – Encodes the request and sends it over the network.
3. **Transport Layer (Network)** – Transfers the request to the remote system.
4. **Stub (Server-Side Proxy)** – Decodes the request.
5. **Server** – Executes the requested procedure and returns the response.

### **RPC Workflow**

1. **Client calls a function**: A client calls a remote function just like a local one.
2. **Marshalling (Serialization)**: The client stub serializes parameters.
3. **Network Communication**: The request is sent over the network.
4. **Server Processing**:
   * Server stub receives the request.
   * It deserializes (unmarshalls) the parameters.
   * The actual function is executed.
5. **Response Transmission**:
   * The server stub serializes the response and sends it back.
   * The client stub receives and deserializes the response.
   * The client receives the result as if it were a local function call.

### **Example: RPC API in gRPC (Google RPC with Protocol Buffers)**

Let's build an RPC API using **gRPC** (a modern high-performance RPC framework developed by Google).

#### **1. Define the RPC Service (Protocol Buffers)**

We use **Protocol Buffers (protobuf)** to define the RPC methods and data structures.

```protobuf
// calculator.proto
syntax = "proto3";

service Calculator {
  rpc Add (AddRequest) returns (AddResponse);
}

message AddRequest {
  int32 a = 1;
  int32 b = 2;
}

message AddResponse {
  int32 result = 1;
}

```

#### **2. Generate gRPC Code**

After defining the `.proto` file, use the gRPC compiler (`protoc`) to generate client and server code in the desired programming language.

```sh
protoc --go_out=. --go-grpc_out=. calculator.proto

```

#### **3. Implement the Server (Go)**

The server implements the defined RPC methods.

```go
package main

import (
    "context"
    "log"
    "net"

    "google.golang.org/grpc"
    pb "path/to/generated/calculatorpb"
)

type server struct {
    pb.UnimplementedCalculatorServer
}

func (s *server) Add(ctx context.Context, req *pb.AddRequest) (*pb.AddResponse, error) {
    result := req.A + req.B
    return &pb.AddResponse{Result: result}, nil
}

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

    grpcServer := grpc.NewServer()
    pb.RegisterCalculatorServer(grpcServer, &server{})

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

```

#### **4. Implement the Client (Go)**

The client makes an RPC call to the server.

```go
package main

import (
    "context"
    "log"
    "time"

    "google.golang.org/grpc"
    pb "path/to/generated/calculatorpb"
)

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

    client := pb.NewCalculatorClient(conn)

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

    req := &pb.AddRequest{A: 10, B: 20}
    res, err := client.Add(ctx, req)
    if err != nil {
        log.Fatalf("Error calling Add: %v", err)
    }

    log.Printf("Addition Result: %d", res.Result)
}

```

### **Types of RPC**

1. **Synchronous RPC** – The client waits for a response before proceeding.
2. **Asynchronous RPC** – The client does not wait and continues execution, fetching the result later.
3. **Streaming RPC** – The client and server exchange multiple messages in a single RPC call (e.g., bidirectional streaming in gRPC).

### **Advantages of RPC**

* **Simplicity** – Calls appear as local function calls.
* **Performance** – More efficient than REST over HTTP (especially with gRPC).
* **Streaming Support** – Enables real-time communication.
* **Strongly Typed** – Enforces structured communication with Protocol Buffers.

### **Disadvantages of RPC**

* **Tightly Coupled** – Client and server need shared interfaces.
* **Complex Debugging** – More challenging than REST APIs.
* &#x20;**Language Constraints** – Requires language-specific bindings.

### **When to Use RPC?**

* **Microservices Communication**: Efficient for service-to-service calls.
* **Real-Time Applications**: Streaming capabilities make it ideal for real-time systems.
* **High-Performance Systems**: Faster and lightweight compared to REST.

### **Conclusion**

RPC APIs provide a powerful way to enable distributed computing with minimal overhead. Modern implementations like **gRPC** improve efficiency, making it a great choice for microservices and high-performance applications. 🚀
