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

TypeShapeExample useIn our repo
Unary1 request → 1 responsemost callsall 3 services
Server streaming1 request → stream of responsesa live feedtom (chat)
Client streamingstream of requests → 1 responsea file uploadbob (assets)
Bidirectionalstreams both waysreal-time chatnone

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:20
func (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

client stub SendEmail(ctx, req) │ (HTTP/2, Protobuf-encoded) ▼ ┌─ interceptor chain ──────────────────────────────┐ │ tags → log → recovery → timeout(5s) │ ← Part 4 │ → AUTH: read `token` metadata, verify JWT, │ ← metadata: Part 3 │ inject claims into ctx → tracer │ └───────────────────────────────────────────────────┘ ▼ your handler SendEmail(ctx, *SendEmailRequest) │ reads claims from ctx (tenant, user) ▼ return (*SendEmailResponse, nil) → status OK or (nil, status.Error(codes.X, msg)) → status error ← Part 3
Anchor — every concept has a home That single call touches the whole course: it was registered via 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.
Why not just REST? Because that request was typed end-to-end (the stub and handler share 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.
Read / do this next

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.

grpc.io — core concepts
grpc.io — Go basics tutorial

Check yourself (from memory)

Q1. A unary gRPC handler in Go has the shape…

Context first, request pointer, then response pointer + error. Streaming handlers get a stream object instead (Part 2).

Q2. Before your handler runs, a request passes through…

Tags → log → recovery → timeout → auth → tracer, then your handler. Auth reads the token metadata and injects claims. Part 4.

Q3. All RPCs in our three services are…

Unary only. Streaming examples live in tom (server-stream) and bob (client-stream); no bidi anywhere in the repo.
Trace a SendEmail unary call from stub to response, naming each stage.
recall, then click to reveal
The client calls the generated stub → over HTTP/2 to the server → the request passes the interceptor chain (tags/log → recovery → timeout → auth: verify JWT from 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).
🎓 That's Part 1 — the foundations You can explain what gRPC is, read a Protobuf contract, know how it becomes Go, and trace a unary call. Part 2 opens up the other three RPC types — streaming — using the real examples in tom and bob.
Ready for Part 2 (streaming RPCs), or want a quick mixed quiz across Lessons 1–4 first? Ask me.

1. gRPC — RPC life cycle & the four method types.