Protocol buffers
Table of contents
To begin, you will be creating your own protocol buffers to support a new RPC call.
Background
To be able to send gRPC requests from the client to the server, we need to specify how to serialize and deserialize both client requests and server replies. Google’s Protocol buffers make this much easier by providing a serialization format that can be exported to services in various languages. In this lab, both your client and server will be in Rust, but you may conceivably have a client and server in two different languages (this is commonly done in practice, especially when a frontend written in Javascript or Python needs to interface with a backend written in Go or Rust).
Let’s take a look at the protocol buffer specifications, written in a definition language created by Google, that have been provided to you in proto/kv_store.proto
.
syntax = "proto3";
package kv_store;
service KvStore {
rpc Example (ExampleRequest) returns (ExampleReply) {}
}
message ExampleRequest {
uint32 input = 1;
}
message ExampleReply {
uint32 output = 1;
}
The first two lines of code are not too critical to understand, but the first line specifies the version of protocol buffers we are using, while the package kv_store
line tells the proto compiler to export the protocol buffers to a kv_store
package in the relevant language.
The service KvStore
block specifies the API that the KV store server exposes. Specifically, it tells us that clients can send an ExampleRequest
to the server by calling the Example
RPC, and that the server will send back an ExampleReply
to the client.
The message ExampleRequest
and message ExampleReply
blocks specify the content of the messages passed between the client and server. Specifically, the client sends a 32-bit unsigned integer input to the server, and receives a 32-bit unsigned integer output.
Taking a closer look at the field definitions, the first element (e.g. uint32
) gives the type of the field and the second element (e.g. input
) gives the name of the field. The number at the end is called the field number, which is used to identify fields in the binary encoded data. These numbers are kept the same between different versions of a service, allowing for backward compatibility even when field names or the fields themselves change.
You don’t need to fully understand what these field numbers are doing since you will not be deploying different versions of this assignment, but just make sure you use unique field numbers to distinguish fields within a single message (i.e. the first field should have field number 1, the second field number 2, and so on).
Echo RPC
Modify proto/kv_store.proto
to include an Echo
RPC, where a client sends a message string to the server, and receives that same message string back in the server’s reply. In addition to modifying the service KvStore
block, you will need to create EchoRequest
and EchoReply
messages. If you have not already, it may help to take a look at the Introduction to gRPC article. You will be implementing this RPC’s functionality in the next part.
It is generally good to use a consistent naming convention. In this lab (and on the MapReduce homework), use the convention than an RPC named
Foo
takes in a message calledFooRequest
and returns a message calledFooReply
.