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
- Define service in .proto → generate code → implement server → create client
- Server: inherit generated Service class, override RPC methods
- Client: create Channel → create Stub → call methods
- grpcurl for quick testing (like curl for REST)