Skip to Content
Course content

198: Setting Up gRPC in Ruby

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Which gems do I actually need to get this running?

You don't need a massive list of dependencies, but there's a distinction you need to make between the runtime and the development tools. For the actual application to run, you need the grpc gem. However, to actually generate the Ruby code from your service definitions, you need grpc-tools. I usually put grpc-tools in my development group in the Gemfile because you don't want that overhead in your production environment.

gem 'grpc'
gem 'grpc-tools', group: :development

Once those are installed, you're set. The grpc-tools gem provides the grpc_tools_ruby_protoc binary, which is the engine that reads your Protocol Buffer files and spits out the Ruby classes you'll use to build your server and client.

How do I define the service and generate the Ruby files?

gRPC is "contract-first," meaning we don't start with Ruby code; we start with a .proto file. Let's say we're building a Ride-Sharing app. We need a service that allows a passenger to request a ride. I'd create a file called ride_service.proto like this:

syntax = "proto3";

package rideshare;

service TripService {
  rpc RequestRide (RideRequest) returns (RideResponse) {}
}

message RideRequest {
  string passenger_id = 1;
  string pickup_location = 2;
  string destination = 3;
}

message RideResponse {
  string trip_id = 1;
  string driver_name = 2;
  int32 estimated_arrival_minutes = 3;
}

Now, here is the part that trips people up: you have to compile this. You run a command in your terminal to generate the Ruby "stubs." I recommend outputting them into a lib directory so they stay organized.

grpc_tools_ruby_protoc -I . --ruby_out=lib --grpc_out=lib ride_service.proto

This creates two files in your lib folder: ride_service_pb.rb (the data messages) and ride_service_services_pb.rb (the service definition). Don't try to edit these files manually; if you change the proto file, just run the command again and overwrite them.

How do I turn those generated files into a functioning server?

Now that we have the stubs, you need to implement the actual logic. You do this by creating a class that inherits from the generated Service class. In our ride-sharing example, the generated class will be Rideshare::TripService::Service.

I've found that it's cleanest to separate the service logic from the server startup code. Here is how I'd implement the server:

require 'grpc'
require_relative 'lib/ride_service_pb'
require_relative 'lib/ride_service_services_pb'

class TripServer < Rideshare::TripService::Service
  def request_ride(ride_req, _call)
    puts "Processing ride request for passenger #{ride_req.passenger_id}..."
    
    # In a real app, you'd query a database or a driver-matching algorithm here
    Rideshare::RideResponse.new(
      trip_id: "TRIP-#{rand(1000)}",
      driver_name: "Alex",
      estimated_arrival_minutes: 5
    )
  end
end

def main
  s = GRPC::RpcServer.new
  s.add_http2_port('0.0.0.0:50051', :this_port_is_secure => false)
  s.handle(TripServer.new)
  puts "Ride server running on 0.0.0.0:50051..."
  s.run_till_terminated_or_interrupted([1])
end

main

Note the _call parameter in the request_ride method. Even if you don't use it, gRPC passes metadata and call-specific info there. I use the underscore prefix to tell Ruby (and other devs) that I'm intentionally ignoring that argument.




📋 Practical Task

Implement a Driver Status Update Service

You need to expand the ride-sharing system. Currently, we can request a ride, but the server doesn't know if drivers are available. Your task is to add a new RPC method to the existing gRPC setup.

  • Modify the Proto: Update ride_service.proto to include a new RPC method called UpdateDriverStatus. It should take a DriverStatusRequest (containing driver_id and is_available) and return a StatusResponse (containing a success boolean).
  • Regenerate: Run the grpc_tools_ruby_protoc command to update your Ruby stubs.
  • Implement the Logic: Update the TripServer class to handle the update_driver_status call. For now, simply print the driver's ID and availability to the console and return a successful response.
  • Test: Start your server and ensure it boots without errors now that the new method is implemented.
Rating
0 0

There are no comments for now.

to be the first to leave a comment.