Define a gRPC Service

A gRPC service is essentially a group of related RPC endpoints—exactly how they’re related is up to you. A common example is a RESTful grouping where the relation is that the endpoints operate on the same resource, but the grouping could be looser than that. In general, it’s just a group of endpoints needed to solve some problem. In our case, the goal is to enable people to write to and read from their log.

Creating a gRPC service involves defining it in protobuf and then compiling your protocol buffers into code comprising the client and server stubs that you then implement. To get started, open log.proto, the file where we defined our Record message, and add the following service definition above those messages:

ServeRequestsWithgRPC/api/v1/log.proto
 service​ Log {
 rpc​ Produce(ProduceRequest) ​returns​ (ProduceResponse) {}
 rpc​ Consume(ConsumeRequest) ​returns​ (ConsumeResponse) {}
 rpc​ ConsumeStream(ConsumeRequest) ​returns​ (stream ConsumeResponse) {}
 rpc​ ProduceStream(stream ProduceRequest) ​returns​ (stream ProduceResponse) {}
 }

The service keyword says that this is a service for the compiler to generate, and each RPC line is an endpoint in that service, specifying the type of request and response the endpoint accepts. The requests and responses are messages that the compiler turns into Go structs, like the ones we saw in the previous chapter.

We have two streaming endpoints:

Below your service definition, add the following code to define our requests and responses:

ServeRequestsWithgRPC/api/v1/log.proto
 message​ ProduceRequest {
  Record record = 1;
 }
 
 message​ ProduceResponse {
 uint64​ offset = 1;
 }
 
 message​ ConsumeRequest {
 uint64​ offset = 1;
 }
 
 message​ ConsumeResponse {
  Record record = 2;
 }

The request includes the record to produce to the log, and the response sends back the record’s offset, which is essentially the record’s identifier. Similarly with consuming: the user specifies the offset of the logs they want to consume, and the server responds back with the specified record.

To generate the client- and server-side code with our Log service definition, we need to tell the protobuf compiler to use the gRPC plugin.