Generating Code & Your First gRPC Service
⚙️ Generating Code & Your First gRPC Service
.proto file into real, runnable client and server code.
Service Definition Syntax
A service groups related RPC methods together, the way a class groups methods — a structurally different grouping principle from REST's "group by resource URL."
rpc MethodName(RequestType) returns (ResponseType); is the whole shape of a basic call — a named method, one request message type, one response message type.
The protoc Compiler
protoc reads a .proto file and, via language-specific plugins, generates real source code — client stubs and server base code — in whichever language each service needs.
What Gets Generated
Two things come out of this process, both from the same .proto source — the concrete payoff of Chapter 2's "can't drift apart" claim:
- A client stub — a class with a method matching each
rpcdefinition, handling all the connection, serialization, and network plumbing internally. Calling it looks like calling a normal local function. - A server base/interface — generated routing and deserialization code, leaving exactly one thing for a developer to write: the actual method body implementing the business logic.
A Basic Unary Call End-to-End
A unary RPC — one request, one response — is the simplest of Chapter 4's four streaming modes, and the right starting point.
Writing a REST Handler vs. Implementing a gRPC Method
REST Route Handler
Manually parse the request body, validate it, call business logic, manually serialize the response — all written by hand, every time.
gRPC Method Implementation
Parsing and serialization are already handled by generated code — the method body is just the business logic itself.
| Term | Meaning |
|---|---|
| Service definition | A named group of RPC methods in a .proto file |
| Unary RPC | One request, one response — the simplest call shape |
protoc | The Protocol Buffers compiler that generates language-specific code |
| Client stub | Generated code a client calls — handles serialization/networking internally |
| Server base/interface | Generated routing/deserialization code a developer implements method bodies against |
💻 Coding Challenges
Challenge 1: Write a Service Definition
Using Challenge 1's Order message from Chapter 2, write a service called OrderService with a unary rpc method GetOrder taking an id (int32) and returning an Order.
Goal: Practice writing the rpc MethodName(Request) returns (Response) syntax against a real message type.
Challenge 2: Identify What's Generated
For a .proto file defining UserService with one rpc method, list what protoc would generate on both the client and server side, and what a developer still has to write by hand.
Goal: Practice distinguishing generated code from the one piece that's never auto-generated: business logic.
Challenge 3: REST Handler vs. gRPC Method
Explain, using this chapter's comparison, why implementing a gRPC method body is typically shorter than an equivalent REST route handler, even for the exact same underlying business logic.
Goal: Practice articulating specifically which work moved from "written by hand" to "generated" and why.
Editing a .proto file doesn't automatically update the generated client/server code sitting in the project — protoc has to be re-run explicitly every time the schema changes. A common, easy-to-hit workflow mistake: adding a new field or method to the .proto file, then testing against stale generated stubs that still reflect the old schema, producing confusing "field doesn't exist" errors that have nothing to do with the actual code being written. Most real projects wire stub regeneration into a build script or CI step specifically to prevent stale generated code from ever being an option.
🎯 What's Next
The next chapter covers The Four Streaming Modes — unary (just covered), server-streaming, client-streaming, and bidirectional streaming, and when each genuinely fits.