Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Practical gRPC

You're reading from   Practical gRPC Build highly-connected systems with a framework that can run on any platform

Arrow left icon
Product type Paperback
Published in Nov 2019
Publisher
ISBN-13 9781839211744
Length 169 pages
Edition 1st Edition
Languages
Tools
Arrow right icon
Authors (6):
Arrow left icon
Robert Ross Robert Ross
Author Profile Icon Robert Ross
Robert Ross
Carles Sistare Carles Sistare
Author Profile Icon Carles Sistare
Carles Sistare
Joshua B. Humphries Joshua B. Humphries
Author Profile Icon Joshua B. Humphries
Joshua B. Humphries
Backstop Media LLC Backstop Media LLC
Author Profile Icon Backstop Media LLC
Backstop Media LLC
David Konsumer David Konsumer
Author Profile Icon David Konsumer
David Konsumer
David Muto David Muto
Author Profile Icon David Muto
David Muto
+2 more Show less
Arrow right icon
View More author details
Toc

Creating and using stubs

At this point in this chapter, we have a server that exposes a service implementation. Now we focus on the client side. Before a client can send RPCs to the server, it must first establish a connection to the server and then create a stub, whose methods are invoked to send RPCs to the server.

The mechanism for creating a gRPC client, establishing a connection to a server, and instantiating stubs differs from one target language to another. The gRPC documentation site’s tutorials provides examples for each of the officially supported languages.

The examples below will show the steps for building a Ruby client. At the end, we’ll have a Ruby client that is issuing RPCs to our Go server, demonstrating the interoperability across languages.

Before we start writing Ruby code, we’ll first generate the Ruby code from our proto source file. Ruby code generation for messages and enums is built into a protoc, so no plugin is needed. We will need a plugin, however, to generate the gRPC-specific pieces. All gRPC plugins (other than for Go, Java, and Dart) are in the main gRPC repo, which is also where you will find installation instructions: https://github.com/grpc/grpc/blob/master/INSTALL.md.

After installing everything and building the gRPC repo from source, you can then use the gRPC Ruby plugin (aptly named grpc_ruby_plugin):

protoc --ruby_out=. --grpc_out=. \
    --plugin=protoc-gen-grpc="$(which grpc_ruby_plugin)" \
    ./proto/sfapi.proto

The --ruby_out parameter triggers the standard Ruby code generation, which is for messages and enums defined in the proto source. The --grpc_out parameter then triggers gRPC-specific code generation for Ruby. (It generates Ruby, not some other language, because of the --plugin argument, telling it to invoke grpc_ruby_plugin).

Like in the earlier example, when generating Go code, the arguments to these --*_out parameters is ., which tells protoc to generate code relative to the current directory. This will end up generating Ruby source files in the same location as the proto source, in the ./proto directory.

Dialing the server

Now that we have Ruby code for our gRPC service, the first thing our client code must do is to connect to our running server. Only after a connection is established can we start sending RPCs to the server.

In Ruby, creating the connection and the stub is all done in one step. It is important to note that this means that stubs are not cheap to construct in Ruby as they are in other languages such as Go or Java, because they are coupled with a stateful connection to the server.

Below is an example that constructs the stub by dialing the server, which has defaulted to listening on port 8080:

Ruby

$LOAD_PATH.unshift File.expand_path("../", __FILE__)
require_relative './proto/sfapi_pb'
require_relative './proto/sfapi_services_pb'

stub = Starfriends::Stub.new("localhost:8080", :this_channel_is_insecure)

# Now we can use the stub to make RPCs
# ...

Here’s an equivalent program, but written in Go, to demonstrate how the connection is first setup, and then stubs are cheap wrappers around the connection:

Go

package main

import (
  "google.golang.org/grpc"

  "./proto"
)

func main() {
  // First we create the connection:
  conn, err := grpc.Dial("localhost:8080", grpc.WithInsecure())
  if err != nil {
    panic(err)
  }

  // We can now create stubs that wrap conn:
  stub := proto.NewStarfriendsClient(conn)

  // Now we can use the stub to make RPCs
  // ...
}

Here you can see the two steps. The conn object is a stateful connection to the server, and stub is a cheap wrapper that can be used to issue RPCs. The NewStarfriendsClient factory method was created by protoc. Such a factory is generated for each service in the proto source.

Working with stubs

Now that you have a stub, you can invoke methods that result in sending RPCs to the Go server:

Ruby

# First we create the request message
request = GetFilmRequest.new(id: '4')
# Now we can use stub (created in the Ruby example above)
# to send an RPC to the server and get back the response
response = stub.get_film(request)

puts response.inspect

The above snippet issues the RPC and prints the response, which has the details for the movie with ID “4”. The output looks like so:

<GetFilmResponse: film: <Film: id: "4", title: "A New Hope", director: "George Lucas",
producer: "Gary Kurtz, Rick McCallum", release_date: <Google::Protobuf::Timestamp:
seconds: 233380800, nanos: 0>>>

One interesting thing to note is that protoc converted the name of the method, which was defined as GetFilm in the proto source, to idiomatic naming conventions for Ruby methods: get_film. It does this for all languages, translating names in the IDL into names that should feel “at home” in the language of the generated code.

The stub has one method for each method defined in the service. The kind of request each method expects is the same as defined in the proto IDL, and the kind of message that is returned also matches the response type defined in the proto IDL.

lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime