Most teams don't choose an API paradigm badly because they don't understand REST, GraphQL, gRPC, or event-driven messaging — they understand all four reasonably well. They choose badly because the decision gets made once, early, based on whichever paradigm the last project used or whichever one is loudest in the industry that year, and then every subsequent boundary gets forced into that same mold regardless of whether it actually fits. A public-facing CRUD resource, an internal high-throughput service call, and a fan-out notification to a dozen downstream systems are three genuinely different problems, and treating them as one problem because they happen to live in the same codebase is where the real cost accumulates.
This lesson is an exercise, not a survey: a structured, repeatable sequence of questions you apply to one API boundary at a time — one endpoint, one service-to-service call, one integration point — that turns "which protocol should I use" from a preference into a traceable decision. It will not tell you REST is always right for public APIs or gRPC is always right for internal ones, because neither claim survives contact with a real system. It will give you the specific axes that actually determine fit, in the order that matters, and a worked scenario to run them against.
Get this decision wrong at a boundary that later has to scale, and the fix is not a quick refactor — it's a protocol migration touching every client that has ever integrated against it, exactly the kind of expensive, multi-team, multi-quarter project Lesson 33's migration strategies exist to manage after the fact. Getting the choice right at design time is a conversation. Getting it wrong and fixing it later is a program.
Analogy🏏Cricket
🏏 Think of it like cricket: A captain does not open the bowling with whichever bowler took wickets in the last match regardless of today's conditions — the decision runs through a specific set of signals every time: is the pitch offering early seam movement, is the batsman right- or left-handed, is this the powerplay or a settled middle-overs passage, how many overs does a strike bowler have left to use later. Rohit Sharma bringing on Kuldeep Yadav for a left-arm wrist-spin match-up against a specific batsman, and holding Jasprit Bumrah back for a death-overs situation instead, is not habit — it is reading which specific tool fits which specific conditions, made fresh for that match rather than copied from the last one. A captain who opened every innings with the same bowler regardless of conditions because it worked once would eventually hand an easy match-up to a batsman it was never suited to face. Just as a bowling change is chosen by reading the pitch, the batsman, and the match phase rather than by habit, an API paradigm should be chosen by reading the consumer, the latency budget, and the coupling need at that specific boundary rather than by whichever protocol the team used last time. Just as holding a resource in reserve for the situation it actually suits beats deploying it everywhere out of familiarity, choosing gRPC, GraphQL, REST, or events by fit rather than by preference is what keeps each one earning its place. The insight is that the right tool changes with the situation, and the skill worth building is reading the situation accurately, not memorizing a favorite answer.
🏏 Showing the Cricket analogy — a Cricket version isn’t available for this concept yet.