Chapter 12: Your First gRPC Service

Step 1: Define the Service (.proto)

syntax = "proto3";
package greeter.v1;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply);
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

Step 2: Generate Code

$ protoc --cpp_out=gen/ --grpc_out=gen/ \
    --plugin=protoc-gen-grpc=$(which grpc_cpp_plugin) \
    proto/greeter/v1/service.proto

Step 3: Implement Server (C++)

#include "gen/service.grpc.pb.h"

class GreeterImpl : public greeter::v1::Greeter::Service {
  grpc::Status SayHello(grpc::ServerContext* ctx,
                         const greeter::v1::HelloRequest* req,
                         greeter::v1::HelloReply* reply) override {
    reply->set_message("Hello, " + req->name() + "!");
    return grpc::Status::OK;
  }
};

int main() {
  GreeterImpl service;
  grpc::ServerBuilder builder;
  builder.AddListeningPort("0.0.0.0:50051", grpc::InsecureServerCredentials());
  builder.RegisterService(&service);
  auto server = builder.BuildAndStart();
  server->Wait();
}

Step 4: Implement Client (C++)

auto channel = grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials());
auto stub = greeter::v1::Greeter::NewStub(channel);

greeter::v1::HelloRequest req;
req.set_name("World");

greeter::v1::HelloReply reply;
grpc::ClientContext ctx;

grpc::Status status = stub->SayHello(&ctx, req, &reply);
if (status.ok()) {
  std::cout << reply.message() << std::endl;  // "Hello, World!"
}

Step 5: Test with grpcurl

# grpcurl — like curl but for gRPC
$ grpcurl -plaintext -d '{"name":"World"}' \
    localhost:50051 greeter.v1.Greeter/SayHello
{
  "message": "Hello, World!"
}
Key Takeaways