---
title: gRPC for Beginners
date: 2016-04-11
description: An introduction to Google's gRPC framework covering Protocol Buffers, service definitions, and building clients and servers.
tags: [grpc, go]
---

## Introduction

I started designing a new microservice that I wanted to write in [Go](https://golang.org/). The service was to be a JSON RPC service over TCP, and the expected consumer servicer I would build using [Ruby](https://www.ruby-lang.org/).

I had some initial concerns regarding the nature of TCP sockets with a highly scalable and distrubuted set of services (this was to be utilised within the [BBC](http://www.bbc.co.uk/news) so these are genuine concerns to be had for my purposes) and so I decided to do some research.

There are a few issues that I discovered:

1. TCP connections aren't free (so utilise a connection pool)
1. Too many simultaneous requests can exhaust open port/file descriptors
1. If not careful you can end up with orphaned TCP connections (e.g. if no timeouts configured)

Now these are all things that can be worked around (or I could just build the Go service as a HTTP REST service and some of these problems dissapear). But it seems lots of people have been talking about using Google's new open-source RPC framework called [gRPC](http://www.grpc.io/) and I thought what better time to investigate what it can do.

Google define gRPC as:

> [!CITE]
> A high performance, open source, general RPC framework that puts mobile and HTTP/2 first

### How does it work?

One of the initial benefits is the ability to be able to define and codify your service requirements via a `.proto` file. The proto file is based around another concept Google have been working on known as [Protocol Buffers](https://developers.google.com/protocol-buffers/docs/overview).

In essence, protocol buffers are an open-source mechanism for serializing structured data.

Once you have your service *defined*, you can utilise a command line compiler to generate stubs and code in multiple programming languages. So you can generate a client and server with the Go programming language, and then using the same `.proto` file generate a client/server with Ruby.

Google have built gRPC on top of the [HTTP/2 standard](https://http2.github.io/), meaning you get features such as bidirectional streaming, flow control, header compression and multiplexing requests over a single TCP connection.

> [!TIP]
> See [here](http://www.grpc.io/posts/principles) for Google's "motivation and design principles" around gRPC

Now the reason for this post is that I didn't find the documentation to be that intuitive. I thought I might be able to help people get started more quickly by detailing the steps in a more succinct fashion than found in Google's documentation, thus opening up gRPC to more users.

So with this in mind, let's crack on...

## Install gRPC

First thing we need to do is install gRPC's C based libraries. Once we have this installed we will later install plugin extensions for other programming languages (such as Go and Ruby, but there are other languages available).

One of the things I discovered further along in my research of gRPC (and I wish I had known earlier) was that some commands that are utilised by the language extensions are only available when installing gRPC from source. So that's what we'll be doing now:

- `git clone https://github.com/grpc/grpc.git`
- `cd grpc`
- `git submodule update --init`
- `make`
- `make install`

## Install Proto Buffer Compiler

Now that we have gRPC installed we also need the compiler for the Protocol Buffer definition file. This is the file that defines our service and which we'll get round to writing shortly. In order to install the compiler you'll first need to make sure you have the [requisite dependencies installed](https://github.com/google/protobuf/tree/master/src).

For myself, running this on Mac OS X I just need XCode installed:

```
sudo xcode-select --install
```

Once you do that, you can execute the following steps:

- `git clone git@github.com:google/protobuf.git`
- `./autogen.sh`
- `./configure`
- `make`
- `make check`
- `sudo make install`

> [!INFO]
> each Make target took ~10mins each to run

## Hello World Proto Definition

Protocol Buffers are designed by Google to be language and platform neutral, and so in theory you can use it with your own RPC implementation. But in reality most people will use gRPC with Protocol Buffers.

So with that said, here is our service definition written using the latest syntax (`proto3`) and I've named it `requester.proto`:

```
syntax = "proto3";

package requester;

service Requester {
  rpc Process (Config) returns (Response) {}
}

message Config {
  string data = 1;
}

message Response {
  string message = 1;
}
```

> [!TIP]
> see [here](https://developers.google.com/protocol-buffers/docs/proto3#specifying-field-types) for full proto3 syntax documentation

In summary it defines an RPC service that exposes a `Process` method which can be called remotely. In reality, it's the same 'Hello World' app provided by the gRPC docs but with some changes in identifiers.

### Syntax Explanation

You can see the `package` statement near the top, which according to Google's docs are used to avoid name clashes between protocol messages; but more specifically it effects the way code is compiled/generated.

For example, in Ruby it'll generate a top level module that utilises that namespace. As you'll see shortly, I have two nested modules with the same name `Requester::Requester`. This is because the `package` setting is the top level and the nested module name is because that's what I named the `service`. So be careful what you name it as the compiled code might not be what you want.

> [!INFO]
> because the design has come from Google you're going to notice lots of design considerations that correlate to their opinions and choices with the Go programming language

In Go, the other language we're using, the `package` value is used (conveniently) as the name of the Go package. Which makes sense as there is a closer correlation in the design of Protocol Buffers and Go vs a dynamic language such as Ruby.

Inside of the `service` statement we state that we want an RPC service that has a `Process` method and that method accepts something of type `Config` and returns something of type `Response`. We can then define what `Config` and `Response` look like, which we do using the `message` statement.

So to keep things simple I've only used a single property setting for each message, but there is a rich selection of data types you can utilise. In my simple example both properties have a `string` type.

You can then access these properties from your code as a nested object field/property. So in Ruby, for example, if you accepted the message `Config` as an argument `c` to your `Process` method then your code would call `c.data`.

The numbers assigned to the property (e.g. both `data` and `message` are assigned the value `1`) are known as 'tags'. Effectively, tags with a number between 1 and 15 take one byte to encode whereas tags between 16 and 2047 take two bytes to encode.

The idea is that you should reserve the tags 1 through 15 for very frequently occurring message elements. But if you really want all the gory details then I'll refer you to the [encoding documentation](https://developers.google.com/protocol-buffers/docs/encoding).

### Auto Generating Service Code

So at this point we have the option of auto-generating 'service code' for any of the languages gRPC supports, which is:

- C
- C#
- C++
- Go
- Java
- Node.js
- Objective-C
- PHP
- Python
- Ruby

We're interested in Go and Ruby as I want to have the RPC service server side running in Go but have the consumer in Ruby. So I'll first generate the Ruby client stub using the `protoc` compiler we installed earlier:

```
protoc --ruby_out=lib \
--grpc_out=lib \
--plugin=protoc-gen-grpc=`which grpc_ruby_plugin` ./requester.proto
```

> [!TIP]
> execute `mkdir lib` if that directory doesn't already exist

This will generate two files `requester.rb` and `requester_services.rb` inside of the `lib` directory we've specified. The content of those files looks like the following. The first file being `requester.rb`:

```
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# source: requester.proto

require 'google/protobuf'

Google::Protobuf::DescriptorPool.generated_pool.build do
  add_message "requester.Config" do
    optional :name, :string, 1
  end
  add_message "requester.Response" do
    optional :message, :string, 1
  end
end

module Requester
  Config = Google::Protobuf::DescriptorPool.generated_pool.lookup("requester.Config").msgclass
  Response = Google::Protobuf::DescriptorPool.generated_pool.lookup("requester.Response").msgclass
end
```

Here is the second file `requester_services.rb`:

```
# Generated by the protocol buffer compiler.  DO NOT EDIT!
# Source: requester.proto for package 'requester'

require 'grpc'
require 'requester'

module Requester
  module Requester

    # TODO: add proto service documentation here
    class Service

      include GRPC::GenericService

      self.marshal_class_method = :encode
      self.unmarshal_class_method = :decode
      self.service_name = 'requester.Requester'

      rpc :Process, Config, Response
    end

    Stub = Service.rpc_stub_class
  end
end
```

We'll see how to consume these stubs from Ruby in the next section. But now let's move onto how to use `protoc` to generate some Golang stubs:

```
protoc --go_out=plugins=grpc:pb ./requester.proto
```

So in the above example the `pb` reference is to a folder that has to exist before you run that command. You can name the folder whatever you like obviously, but `pb` (protocol buffer) made sense to me.

The file that is generated will be named `requester.pb.go` and (as with the Ruby code) we'll look at how to consume this file in a following section that demonstrates the Go code examples. But for now let's see the contents of this file (shield your eyes, Go isn't the most concise programming language):

```
// Code generated by protoc-gen-go.
// source: requester.proto
// DO NOT EDIT!

/*
Package requester is a generated protocol buffer package.

It is generated from these files:
  requester.proto

It has these top-level messages:
  Config
  Response
*/
package requester

import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"

import (
  context "golang.org/x/net/context"
  grpc "google.golang.org/grpc"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
const _ = proto.ProtoPackageIsVersion1

type Config struct {
  Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
}

func (m *Config) Reset()                    { *m = Config{} }
func (m *Config) String() string            { return proto.CompactTextString(m) }
func (*Config) ProtoMessage()               {}
func (*Config) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }

type Response struct {
  Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"`
}

func (m *Response) Reset()                    { *m = Response{} }
func (m *Response) String() string            { return proto.CompactTextString(m) }
func (*Response) ProtoMessage()               {}
func (*Response) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }

func init() {
  proto.RegisterType((*Config)(nil), "requester.Config")
  proto.RegisterType((*Response)(nil), "requester.Response")
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion1

// Client API for Requester service

type RequesterClient interface {
  Process(ctx context.Context, in *Config, opts ...grpc.CallOption) (*Response, error)
}

type requesterClient struct {
  cc *grpc.ClientConn
}

func NewRequesterClient(cc *grpc.ClientConn) RequesterClient {
  return &requesterClient{cc}
}

func (c *requesterClient) Process(
    ctx context.Context, in *Config, opts ...grpc.CallOption
) (*Response, error) {
  out := new(Response)
  err := grpc.Invoke(ctx, "/requester.Requester/Process", in, out, c.cc, opts...)
  if err != nil {
    return nil, err
  }
  return out, nil
}

// Server API for Requester service

type RequesterServer interface {
  Process(context.Context, *Config) (*Response, error)
}

func RegisterRequesterServer(s *grpc.Server, srv RequesterServer) {
  s.RegisterService(&_Requester_serviceDesc, srv)
}

func _Requester_Process_Handler(
    srv interface{}, ctx context.Context, dec func(interface{}) error
) (interface{}, error) {
  in := new(Config)
  if err := dec(in); err != nil {
    return nil, err
  }
  out, err := srv.(RequesterServer).Process(ctx, in)
  if err != nil {
    return nil, err
  }
  return out, nil
}

var _Requester_serviceDesc = grpc.ServiceDesc{
  ServiceName: "requester.Requester",
  HandlerType: (*RequesterServer)(nil),
  Methods: []grpc.MethodDesc{
    {
      MethodName: "Process",
      Handler:    _Requester_Process_Handler,
    },
  },
  Streams: []grpc.StreamDesc{},
}

var fileDescriptor0 = []byte{
  // 172 bytes of a gzipped FileDescriptorProto
  0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x2f, 0x4a, 0x2d, 0x2c,
  0x4d, 0x2d, 0x2e, 0x49, 0x2d, 0xd2, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x84, 0x0b, 0x28,
  0xc9, 0x70, 0xb1, 0x39, 0xe7, 0xe7, 0xa5, 0x65, 0xa6, 0x0b, 0x09, 0x71, 0xb1, 0xe4, 0x25, 0xe6,
  0xa6, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0x70, 0x06, 0x81, 0xd9, 0x4a, 0x2a, 0x5c, 0x1c, 0x41, 0xa9,
  0xc5, 0x05, 0xf9, 0x79, 0xc5, 0xa9, 0x42, 0x12, 0x5c, 0xec, 0xb9, 0xa9, 0xc5, 0xc5, 0x89, 0xe9,
  0x30, 0x25, 0x30, 0xae, 0x91, 0x03, 0x17, 0x67, 0x10, 0xcc, 0x40, 0x21, 0x63, 0x2e, 0xf6, 0x80,
  0xa2, 0xfc, 0x64, 0xa0, 0x94, 0x90, 0xa0, 0x1e, 0xc2, 0x62, 0x88, 0x25, 0x52, 0xc2, 0x48, 0x42,
  0x30, 0x93, 0x95, 0x18, 0x9c, 0x8c, 0xb9, 0xa4, 0x32, 0xf3, 0xf5, 0xd2, 0x8b, 0x0a, 0x92, 0xf5,
  0x52, 0x2b, 0x12, 0x73, 0x0b, 0x72, 0x52, 0x8b, 0x11, 0x0a, 0x9d, 0xf8, 0xe0, 0xa6, 0x07, 0x80,
  0x9c, 0x1f, 0xc0, 0xb8, 0x88, 0x89, 0x29, 0x28, 0x30, 0x89, 0x0d, 0xec, 0x19, 0x63, 0x40, 0x00,
  0x00, 0x00, 0xff, 0xff, 0xac, 0xd0, 0xf7, 0x73, 0xdf, 0x00, 0x00, 0x00,
}
```

## Ruby Example

OK, so we've defined what our service does: it's an RPC service that exposes a `Process` method that takes an argument. But what that method returns we've yet to build (that's not the responsibility of the definition file).

We've used the `protoc` compiler to auto-generate some code stubs for us, which handle the setting up of the service. So let's see how we consume that from Ruby, we're going to need the following files:

- `Gemfile`
- `server.rb`
- `client.rb`

This is what the contents of those files look like...

### Gemfile

```
source "https://rubygems.org/"

gem "grpc", "~> 0.11"
```

We only have one dependency, which is the `grpc` extension.

### server.rb

```
$: << File.join(File.dirname(__FILE__), "lib")

require "grpc"
require "requester_services"

class RequesterServer < Requester::Requester::Service
  def process(config, _unused_call)
    Requester::Response.new(message: "Hello #{config.name}")
  end
end

s = GRPC::RpcServer.new
s.add_http2_port("0.0.0.0:50051", :this_port_is_insecure)
s.handle(RequesterServer)
s.run_till_terminated
```

So same set of dependencies pulled in, like with the client. But this time we're creating a new instance of a class that inherits from our `Requester::Requester::Service` auto-generated class.

This is similar in essence to the Template Method Pattern, where we're now able to define the implementation of the method type `process`. But one thing to remember is that you need the 2nd argument `_unused_call` that's passed into the `process` method. Remove it and things will break.

Why? I've actually no idea. I've found nothing in the documentation that explains this, and I've sifted through the source code and nothing I could grok to understand why this second (seemingly pointless) argument is there.

From here we create a new gRPC server instance (`GRPC::RpcServer`). We then specify the address and port we want the server to listen to. Don't be fooled in the specific nature of 'http2' in the method `add_http2_port`, there is no `add_http_port` or alternative method.

Also, as before, the `:this_port_is_insecure` is required. I don't really like the design of the code here, but I guess what can you expect from low-level programmers designing code for dynamic languages they typically don't use.

Next we specify our `RequesterServer` to be the instance that handles any incoming requests. Finally we tell the server to run until it's terminated via a signal such as `INT` or `TERM` ([documented here](http://www.rubydoc.info/github/grpc/grpc/7131c62/GRPC/RpcServer#run_till_terminated-instance_method)).

To run this program:

```
bundle install
bundle exec ruby server.rb
```

You wont see anything in the output, so let's move onto the client code...

### client.rb

```
$: << File.join(File.dirname(__FILE__), "lib")

require "grpc"
require "requester_services"

stub = Requester::Requester::Stub.new("localhost:50051", :this_channel_is_insecure)
msg = stub.process(Requester::Config.new(name: "Mark")).message
p "Greeting: #{msg}"
```

Here we're loading our grpc dependency and the service stub that was auto-generated for us. Notice that because my protocol buffer definition file specified the package as `requester` and the file itself was called `requester` I've now got this ugly namespace `Requester::Requester`.

Again, just be aware of what you're naming things because to be honest that double named module is annoying for me to look at. I left it like that to demonstrate why it's important to name things well.

You'll notice that we pass in `:this_channel_is_insecure` to the `Stub.new` method. This isn't an arbitrary value, it needs to be exactly that value otherwise you'll see errors. I've yet to look into using HTTPS/TLS but if you're interested, then you can find the relevant details on the [authentication documentation](http://www.grpc.io/docs/guides/auth.html).

Once we create a new instance of our service, we can now access the `process` method that is exposed by our RPC service. Convention in Ruby is lowercase method names, so although we defined it as `Process` it's accessed as `process`.

We pass into `process` the expected `Config` 'type' (Ruby doesn't have types as part of the language so they've provided us a module/namespace instead to mimic this feature), and finally we call the `message` property on the returned object (remember we defined a Response in our protocol buffer definition file that had a `message` field).

To run this program:

```
bundle install
bundle exec ruby client.rb
```

Which should result in the output:

```
"Greeting: Hello Mark"
```

## Go Example

We can set up our services to use Go completely or we can mix and match. But let's see how to use both the client and server from Go. As with Ruby, we've defined what our service does: it's an RPC service that exposes a `Process` method that takes an argument. But what that method returns we've yet to build.

We've used the `protoc` compiler to auto-generate some code stubs for us, which handle the setting up of the service. So let's see how we consume that from Go, we're going to need the following files:

- `server.go`
- `client.go`

### server.go

```
package main

import (
  "log"
  "net"

  pb "github.com/integralist/test-grpc-custom/pb"
  "golang.org/x/net/context"
  "google.golang.org/grpc"
)

const (
  port = ":50051"
)

type server struct{}

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

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

So the Go variation is fairly straight forward, our `main` function listens on the specified port and we start up a new grpc server instance.

From there we take the protocol buffer `pb/requester.pb.go` that was generated by the `protoc` compiler and call a pre-supplied `pb.RegisterRequesterServer` method and pass in a data structure for it to utilise along with the grpc server.

For the `server` struct type we associate the required `Process` method and define its behaviour. In this case, similar to the Ruby version, we create an instance of the `Response` type.

To run this program, execute:

```
go run server.go
```

### client.go

```
package main

import (
  "log"
  "os"

  pb "github.com/integralist/test-grpc-custom/pb"
  "golang.org/x/net/context"
  "google.golang.org/grpc"
)

const (
  address     = "localhost:50051"
  defaultName = "world"
)

func main() {
  conn, err := grpc.Dial(address, grpc.WithInsecure())
  if err != nil {
    log.Fatalf("did not connect: %v", err)
  }
  defer conn.Close()
  c := pb.NewRequesterClient(conn)

  name := defaultName
  if len(os.Args) > 1 {
    name = os.Args[1]
  }
  r, err := c.Process(context.Background(), &pb.Config{Name: name})
  if err != nil {
    log.Fatalf("could not greet: %v", err)
  }
  log.Printf("Greeting: %s", r.Message)
}
```

With the server program running we can now execute our client to call the server's `Process` method. Again, in summary, we use gRPC's own `Dial` method to call the specified address. The second argument disables the transport security for this particular connection. If you want HTTPS/TLS encryption then you'll need to read the documentation for those details.

We create a new instance of the auto-generated client, and call the `Process` method. Passing along the auto-generated `Config` type with the data we want it to receive.

The `pb` identifier references the auto-generated protocol buffer package (`pb "github.com/integralist/test-grpc-custom/pb"`), and as you'll probably already know this path is unique to your local setup and where you created that package.

To run this program, execute:

```
go run client.go Mark
```

Which should result in the output:

```
"Greeting: Hello Mark"
```

> [!INFO]
> if you leave off the argument "Mark"\
> then the output will default to "Hello world" instead

## Conclusion

So there you go. Hopefully you've found this break down useful. The principles of gRPC seem promising, and although I'm not keen on the design of the auto-generated code being not as 'idiomatic' as you'd expect for a language such as Ruby (I'm not sure what the other language implementations are like) I still think this could be an interesting evolution of the microservices movement.

### Update

There are alternatives that work in a similar fashion, one of which is [Apache Thrift](https://thrift.apache.org/) and is defined as being a "software framework, for scalable cross-language services development". But unfortunately it doesn't support the Go programming language, which is a requirement for me. But interesting nonetheless.
