Lesson 4 · Foundations
A unary call, end-to-end
The four RPC types — then one request/response traced through your SendEmail.
Your win: name the four RPC types, then trace a unary call from client stub to response, seeing where every concept in this course will slot in.
The four RPC types
| Type | Shape | Example use | In our repo |
|---|---|---|---|
| Unary | 1 request → 1 response | most calls | all 3 services |
| Server streaming | 1 request → stream of responses | a live feed | tom (chat) |
| Client streaming | stream of requests → 1 response | a file upload | bob (assets) |
| Bidirectional | streams both ways | real-time chat | none |
We start with unary — the one you'll meet everywhere in conversationmgmt, notification, and spike. Streaming is Part 2.1
A unary handler is just a Go method
internal/spike/modules/email/controller/grpc/email_modifier_send_email.go:20func (svc *EmailModifierService) SendEmail(ctx context.Context,
req *spb.SendEmailRequest) (*spb.SendEmailResponse, error) {
// validate → do work → return response OR a status error
}
Shape to memorise: func(ctx, *Req) (*Resp, error). The first arg is
always context.Context (your Go course, Lesson 17 — it carries the deadline
and the claims).
Trace the call
spb.RegisterEmailModifierServiceServer (Lesson 3); it passed the
interceptor chain (Part 4) where auth read the metadata
token and injected claims; the handler honours the deadline on
ctx (Part 3); and it returns a status (Part 3). Keep this map in
your head — the rest of the course fills it in.
spb.SendEmailRequest), binary-encoded (small), and rode a
reused HTTP/2 connection — none of which hand-rolled REST+JSON gives you for
free. The trade-offs get a full lesson in Part 5.
gRPC — Core concepts (RPC lifecycle) + Go Basics tutorial
Core concepts describes the unary lifecycle and the four types precisely; the Go Basics tutorial has you implement one. Both are the primary sources for Part 2.
Check yourself (from memory)
Q1. A unary gRPC handler in Go has the shape…
Q2. Before your handler runs, a request passes through…
Q3. All RPCs in our three services are…
SendEmail unary call from stub to response, naming each stage.token metadata, inject claims into ctx →
tracer) → the registered SendEmail(ctx, *SendEmailRequest) handler runs →
returns (*SendEmailResponse, nil) on success or
status.Error(codes.X, msg) on failure. To come: streaming (Part 2);
status/metadata/deadlines (Part 3); interceptors (Part 4).