logo
eng-flag

gRPC Cheatsheet

Table of Contents

  1. Introduction to gRPC
  2. Protocol Buffers
  3. Service Definition
  4. Types of gRPC Services
  5. gRPC Concepts
  6. Implementing gRPC Services
  7. Error Handling
  8. Metadata
  9. Interceptors
  10. Deadlines and Cancellation
  11. Load Balancing
  12. Security
  13. Best Practices
  14. Tools

Introduction to gRPC

gRPC is a high-performance, open-source universal RPC framework developed by Google. It uses HTTP/2 for transport, Protocol Buffers as the interface description language, and provides features such as authentication, bidirectional streaming and flow control, blocking or nonblocking bindings, and cancellation and timeouts.

Protocol Buffers

Protocol Buffers (protobuf) is the default serialization mechanism for gRPC. Here's a basic example:

syntax = "proto3";

package example;

message Person {
  string name = 1;
  int32 age = 2;
  repeated string hobbies = 3;
}

message GetPersonRequest {
  string id = 1;
}

service PersonService {
  rpc GetPerson(GetPersonRequest) returns (Person);
}

Service Definition

A gRPC service is defined in a .proto file:

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

Types of gRPC Services

  1. Unary RPC
rpc SayHello(HelloRequest) returns (HelloReply);
  1. Server Streaming RPC
rpc LotsOfReplies(HelloRequest) returns (stream HelloReply);
  1. Client Streaming RPC
rpc LotsOfGreetings(stream HelloRequest) returns (HelloReply);
  1. Bidirectional Streaming RPC
rpc BidiHello(stream HelloRequest) returns (stream HelloReply);

gRPC Concepts

  • Channel: A channel provides a connection to a gRPC server on a specified host and port.
  • Stub: A stub is a client-side object that implements the same methods as the gRPC service.
  • Server: The gRPC server implements the service interface and runs a gRPC server to handle client calls.

Implementing gRPC Services

Example in Go:

type server struct{}

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    return &pb.HelloReply{Message: "Hello " + in.Name}, nil
}

func main() {
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s, &server{})
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}

Error Handling

gRPC uses status codes for error handling:

import "google.golang.org/grpc/codes"
import "google.golang.org/grpc/status"

func (s *server) SomeRPC(ctx context.Context, req *pb.Request) (*pb.Response, error) {
    if someError {
        return nil, status.Errorf(codes.InvalidArgument, "Invalid argument: %v", err)
    }
    // Normal processing
}

Metadata

Metadata is information about a particular RPC call in the form of key-value pairs.

Sending metadata (client-side):

md := metadata.Pairs(
    "key1", "value1",
    "key2", "value2",
)
ctx := metadata.NewOutgoingContext(context.Background(), md)
response, err := client.SomeRPC(ctx, request)

Receiving metadata (server-side):

func (s *server) SomeRPC(ctx context.Context, req *pb.Request) (*pb.Response, error) {
    md, ok := metadata.FromIncomingContext(ctx)
    if ok {
        // Use metadata
    }
    // Process request
}

Interceptors

Interceptors allow you to add custom behavior to RPC calls.

Unary interceptor:

func unaryInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
    log.Printf("before handling. Info: %+v", info)
    resp, err := handler(ctx, req)
    log.Printf("after handling. resp: %+v", resp)
    return resp, err
}

s := grpc.NewServer(grpc.UnaryInterceptor(unaryInterceptor))

Deadlines and Cancellation

Setting a deadline:

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

response, err := client.SomeRPC(ctx, request)
if err != nil {
    statusErr, ok := status.FromError(err)
    if ok && statusErr.Code() == codes.DeadlineExceeded {
        log.Println("Deadline exceeded!")
    }
}

Load Balancing

gRPC supports client-side load balancing. You can use DNS for service discovery and implement custom load balancing policies.

conn, err := grpc.Dial(
    "service:50051",
    grpc.WithBalancerName("round_robin"),
    grpc.WithInsecure(),
)

Security

Using TLS:

creds, err := credentials.NewClientTLSFromFile("cert.pem", "")
if err != nil {
    log.Fatalf("Failed to load credentials: %v", err)
}
conn, err := grpc.Dial("example.com:50051", grpc.WithTransportCredentials(creds))

Best Practices

  1. Use Protocol Buffers wisely: Define reusable messages and avoid deeply nested structures.
  2. Implement proper error handling: Use appropriate status codes and provide detailed error messages.
  3. Use bidirectional streaming judiciously: It's powerful but can be complex to manage.
  4. Implement timeout and cancellation mechanisms to prevent resource leaks.
  5. Use interceptors for cross-cutting concerns like logging, authentication, and monitoring.
  6. Implement proper load balancing for scalability.
  7. Use TLS for secure communication.
  8. Version your APIs to maintain backward compatibility.
  9. Implement health checking for better service discovery and load balancing.
  10. Use gRPC reflection for debugging and dynamic clients.
  11. Optimize for performance: Use appropriate message sizes and consider compression.
  12. Implement proper testing: Unit tests, integration tests, and end-to-end tests.
  13. Document your services and messages thoroughly.
  14. Use code generation tools to reduce boilerplate and ensure consistency.
  15. Monitor your gRPC services using appropriate metrics and tracing.

Tools

  1. Protocol Buffer Compiler (protoc): Compiles .proto files
  2. gRPC CLI: Command-line tool for interacting with gRPC services
  3. BloomRPC: GUI client for gRPC
  4. ghz: gRPC benchmarking and load testing tool
  5. gRPC Gateway: RESTful JSON API for gRPC services
  6. Evans: gRPC client with REPL interface
  7. gRPC Web: gRPC for web clients
  8. Postman: Now supports gRPC requests
  9. grpcurl: Command-line tool for interacting with gRPC servers
  10. grpc-ecosystem: Collection of gRPC ecosystem projects

2024 © All rights reserved - buraxta.com