The Trenches
Stylized waves of water rendered in layered teal and ink tones, in the manner of a Japanese woodblock print.
Engineering Trenches · June 2026

Seven Waysto Talk

A field guide to API design

Every API is a decision about how two programs hold a conversation. There are only a handful of questions that decision answers, and seven names worth knowing. Learn the questions, and the names choose themselves.

The whole field in thirty seconds

An API is a contract for how two machines talk, and there are only a few axes that matter: who speaks first, whether the line stays open, whether you trade one question for one answer or a continuous stream, and whether the bytes are made for a human to read or for a machine to parse. REST borrows the web's own grammar and wins by default. gRPC drops to compact binary for traffic between your own services. GraphQL hands the client a pencil so it can draw exactly the data it wants. Webhooks flip the call so the server tells you. WebSockets keep one line open so the server can push. WebRTC builds a direct line between two people with no server in the middle. And SOAP is the one you reach for when the contract outranks your preferences. Same questions, seven stable answers.

Part I

The Shape of a Conversation

Right now, on the device in your hand, dozens of programs are mid sentence. The weather widget asked for a forecast. Your messages app is waiting to be told the moment a reply lands. A music app is pulling a playlist down in pieces. None of them invented how to talk. Each one picked a pattern that already existed, because the patterns are not infinite.

We treat APIs like a catalogue of competing products, as if choosing one were a matter of taste or fashion. It is not. An API is a decision about the structure of a conversation between two programs, and a conversation has a finite anatomy. Strip away the logos and the marketing, and every one of the seven famous styles is just a stable answer to the same small set of questions.

Anatomytwo programs, one exchange, every time

Here are the questions. Who speaks first? In most conversations one side asks and the other answers, but in some the server is the one who reaches out, and in a few either side may speak at any moment. Does the line stay open? You can hang up after every exchange and dial again next time, or you can keep a single connection alive and reuse it. What is the shape of the exchange? One question for one answer, a single request that triggers a stream of replies, or a continuous duplex where both sides talk over each other. What do the bytes look like? Text that a person can read at the cost of size and speed, or packed binary that only a machine will ever decode. Does anyone remember? A stateless exchange forgets you the instant it ends, which is precisely what lets you add a tenth server on a busy afternoon. And who sits in the middle? A server relaying every byte, or a direct path between two peers with nothing in between.

You do not memorize seven APIs. You learn the questions, and the seven answers fall out.

Keep those questions in your pocket. We will hold each of the seven styles up against them, one at a time, and ask the only three things that matter in practice: when the situation calls for it, why it is shaped the way it is, and how the mechanism actually works. By the end you will have a map, and the map will do the deciding for you.

Part II

REST, the Grammar of the Web

Start here, because almost everything starts here. REST stands for Representational State Transfer, which is an academic name for a simple move: stop inventing your own protocol and borrow the one the web already runs on.

Initiates
Client
Connection
Per request
Shape
Ask, answer
Payload
Text, usually JSON
State
None held

The web already had a grammar long before anyone needed an API. It had verbs, GET to read, POST to create, PUT to replace, DELETE to remove, and it had addresses, the URL. REST says model your domain as a set of resources, give each one an address, and use the verbs that already exist to act on them. You do not design a new language. You speak the one billions of documents already speak.

The request cyclethe client asks with a verb, the server answers with a status

Why it is shaped this way

The quiet genius of REST is the word stateless. The server remembers nothing about you between calls. Every request carries everything it needs to be understood on its own. That sounds like a limitation, and it is the single most valuable property in the whole catalogue, because it means any server can answer any request. That is what lets you put ten identical servers behind a load balancer and add an eleventh when traffic spikes. State is the thing that makes scaling out painful, and REST refuses to hold it by design.

Where it costs you

The resource model is rigid, and that rigidity has a price. A single screen that needs a user, their last five orders, and the shipping status of each order becomes three or four round trips, or one bloated endpoint that returns far more than the screen will ever show. REST is honest plumbing. It is not a precision instrument, and the next two styles exist precisely because of that gap.

Reach for REST when you are modelling a domain as resources, building a public API that other developers must learn quickly, or doing anything where simple and universally understood beats clever. It is the right answer for the large majority of what you will ever build. Make it prove insufficient before you reach past it.
Part III

SOAP, the Formal Contract

If REST is a casual phone call, SOAP is a contract signed in triplicate. It stands for Simple Object Access Protocol, and despite the name it is anything but simple. It is what an API looks like when the consequences of a single wrong or lost message are measured in lawsuits, audits, or someone's medical record.

Initiates
Client
Connection
Per request
Shape
Ask, answer
Payload
XML envelope
State
Optional

Every SOAP message is wrapped in a strict XML structure: an envelope that contains a header and a body. The shape is not decoration. The header is where security tokens, routing rules, and reliability metadata travel, inside the message itself, independent of whatever transport carries it. The body holds the actual call. The whole interface is described up front in a formal contract, so a counterparty can generate code against it without ever talking to you.

Envelope
Header
Security · signature, token, who you are
Reliability · message id, delivery guarantee
Body
TransferFunds( from, to, amount )

Why it survives

Nobody chooses SOAP for a new consumer product, and yet it refuses to die, because it lives where regulation and trust boundaries live. Banks settling money between each other, insurance clearinghouses, government registries, hospital systems exchanging patient records. These systems change slowly, often by law, and they value a binding contract, a paper trail, and security baked into the protocol rather than bolted on afterward. When guaranteed delivery and compliance matter more than a pleasant afternoon for the developer, this is the shape that wins.

Reach for SOAP when you are integrating with an enterprise or regulated counterparty that already speaks it, or when you need message level security and delivery guarantees carried inside the message rather than assumed from the network. Otherwise, walk on by.
Part IV

gRPC, Built for Machines

Here is a first principle that reorganizes everything: text is for humans, and your services are not humans. JSON spends bytes and processor time on every single message describing its own structure, the field names, the braces, the quotes, so that a person could in theory read it. Between two of your own services that no person will ever read, that is pure waste.

Initiates
Either side
Connection
Persistent, HTTP/2
Shape
Four kinds
Payload
Binary, Protobuf
State
Per call

gRPC answers the waste with Protocol Buffers. You define the schema once, the messages and the methods, and both sides compile against it. On the wire you then send only the values, packed into a compact binary layout, with the structure already known to both ends. The result is dramatically smaller and faster to parse, and the schema doubles as the contract. On top of that it rides HTTP/2, which carries many calls over one connection at the same time, so you stop paying the connection setup tax on every request.

The four shapes are the design act

The part people miss is that gRPC is not one conversation shape but four, and choosing among them is the real work. Unary is the familiar one ask for one answer. Server streaming is one request that opens a tap of replies, the right shape for a live feed of a driver's location. Client streaming is a tap flowing the other way, a stream of telemetry or a file sent in chunks. And bidirectional lets both ends speak at once, the shape of a live negotiation between two services.

Four conversation shapesthe orange travels client to server, the teal travels back

Where it costs you

Binary is not friendly. You cannot read it by eye, you need code generation and tooling, and a browser cannot speak raw gRPC without a translating proxy. So gRPC lives inside your own walls, where you control both ends, where latency and throughput are real money, and where a typed contract between services is worth more than human readability you will never use.

Reach for gRPC for service to service traffic inside your own system, especially in a busy microservice mesh where the count of internal calls is large and every millisecond and byte adds up.
Part V

GraphQL, Exactly What You Asked For

REST has a structural mismatch baked in. Its unit is the resource, and the server decides the shape of every response. The client, which actually knows what the screen needs, has no say. That mismatch produces two chronic diseases, and GraphQL is the cure for both.

Initiates
Client
Connection
Per request
Shape
Client shapes it
Payload
Text, JSON
State
None held

The first disease is over fetching: an endpoint hands back a fat object when the screen needed three fields of it. The second is under fetching: the screen needs data from several resources, so the client fires several requests and waits on a waterfall of round trips. GraphQL inverts the authority. The client sends one query describing the exact tree of data it wants, the server resolves precisely that tree, and the answer comes back in a single response. No waste, no waterfall.

Round tripsREST waterfalls across endpoints, GraphQL resolves one precise query

There is a second, quieter gift. A GraphQL schema is self describing. The types and fields can be introspected, so a frontend engineer can discover everything available, and tools can autocomplete and validate a query, without booking a meeting with the backend team. The contract is machine readable and lives in one place.

Where it costs you

You do not delete complexity, you move it from the network onto the server. Arbitrary client queries make caching harder, because every shape is effectively a different request. They open the door to expensive deeply nested queries that you must defend against with depth and cost limits. And the resolver layer that turns a query into data is real engineering. GraphQL earns its keep when many different clients, web, phone, partners, all need different slices of one rich, interconnected graph, and the bottleneck really is round trips and over fetching.

Reach for GraphQL when a complex, connected domain is consumed by varied clients with varied needs, and you want product teams to add a field to the screen without a backend change for every one.
Part VI

Webhooks, the Reverse Call

Everything so far has the client asking and the server answering. Webhooks turn that around, and the reversal is the whole point.

Initiates
Server
Connection
Per event
Shape
One way notice
Payload
Text, JSON
State
None held

Without them, the only way to learn about something new is to keep asking. Your app walks to the mailbox every thirty seconds and checks. That is polling, and it is wasteful twice over: it burns requests that almost always come back empty, and the best case latency is your poll interval. The event you care about might be rare and might be urgent, and polling is bad at both. So invert it. Instead of you asking, the source tells you the instant something happens, by making an HTTP request to a URL you registered with it. The doorbell instead of the trip to the mailbox.

Polling versus pushendless empty checks, against a single notice that arrives when it matters

This is the natural glue between systems you do not own. You cannot hold a socket open to a payment provider forever, and the provider cannot poll you. But the provider can POST to your callback URL the moment a payment settles. That is why webhooks are sometimes called reverse APIs, and why they quietly power most cross company automation.

Where it costs you

You now run a public endpoint, and that comes with duties. Anyone can send a request to it, so you must verify a signature on every delivery. Deliveries can repeat, so your handler must be idempotent, safe to receive twice. And they can retry or arrive out of order, so you cannot assume a tidy sequence. The provider owns sending. You own receiving correctly.

Reach for webhooks to react to events in a system you do not control, automate a workflow across a boundary, or keep two systems in sync without anyone polling. Payment settled, code pushed, order placed.
Part VII

WebSockets, the Open Line

Plain HTTP is call, answer, hang up. To talk again you dial again, and the server can never call you. For anything that changes continuously and unpredictably, a chat, a price, a game, that model fights the problem the whole way.

Initiates
Either side
Connection
Persistent
Shape
Full duplex
Payload
Text or binary
State
Per connection

A WebSocket starts as an ordinary HTTP request and then upgrades into something different: one connection that stays open, over which both ends can send a message the instant they have one, with almost none of the overhead of opening a fresh request each time. The crucial change from REST is direction. The server can push. The moment the price ticks, the server sends it, and the client never had to ask.

Reconnect versus the open lineabove, a handshake every time; below, one line and the server pushing freely

Where it costs you

A persistent connection is stateful, and state is what makes scaling hard. You have to track which server holds which open connection, usually with a shared message bus behind the scenes so that a message can find the right client wherever it landed. The connection survives poorly across flaky mobile networks without careful reconnect logic, and every open client ties up resources on the server. You take all of that on in exchange for one thing: the server can speak the instant it has something to say.

Reach for WebSockets for low latency, high frequency, two way updates in a browser. Chat, collaborative editing, live dashboards, trading screens, multiplayer state.
Part VIII

WebRTC, the Straight Line

The last one is the strangest, because it is barely an API at all. WebRTC is a whole framework, and its reason to exist is a single stubborn fact: for live audio and video between two people, every extra hop is latency you can hear and lag you can see. The lowest latency path is a straight line from one device to the other, with no server relaying a single byte.

Initiates
Either side
Connection
Persistent, direct
Shape
Full duplex
Payload
Binary media or data
State
Per session

When you are on a video call, your picture is not travelling to a company server and then on to the other person. Where it can, it goes straight from your device to theirs, peer to peer. The hard part is not sending the bytes once you have a path. The hard part is finding the path. Both of you sit behind home routers, neither device knows its own public address, and firewalls block uninvited traffic. Two machines that do not know each other's real location somehow have to meet in the open internet.

Finding the direct pathpeers swap addresses through a helper, then the media flows straight across

WebRTC solves this by separating the jobs. A signaling channel, which you provide, often over a WebSocket, lets the two peers exchange the metadata they need to connect. A STUN server tells each peer the public address it appears to have from the outside world. When a direct path genuinely cannot be made, a TURN server steps in to relay, trading away the low latency for a connection that at least works. Once a path is found, the media flows directly, and WebRTC handles the rest on its own: adaptive bitrate, codec negotiation, jitter buffering, packet loss concealment, all aimed at staying under the threshold where a person notices delay.

Where it costs you

It is genuinely the most complex thing in this guide. The signaling is yours to build. TURN relays cost real money and quietly reintroduce the hop you were trying to avoid. And pure peer to peer stops scaling the moment a call has more than a few people, at which point you give up the straight line for a media server that mixes and forwards. The reward is that it is built into every modern browser, with no plugin, and when it works it is the fastest path two devices can share.

Reach for WebRTC for real time audio, video, or low latency data flowing directly between clients. Video calls, voice chat, browser to browser file transfer, latency critical multiplayer.
Part IX

Choosing, in Practice

Lay the seven out on the two axes that separate them most cleanly. Across the bottom, how tightly the two ends are bound together, from loose and public on the left to tightly coupled and internal on the right. Up the side, the shape of time, from a single exchange at the bottom to a continuous real time flow at the top. Almost every decision is really a question of where your problem sits on this map.

The mapwhere each style lives, and therefore where your problem points

A working procedure, in the order you should actually run it. Start at REST. It is the default for a reason and it clears most of the field, because most of what you build is a domain you can model as resources, read and written by clients that never need to be told something they did not ask for. If both ends are yours and you are paying for every millisecond and every byte, drop to gRPC. If many different clients each want a different slice of one rich graph and the pain is round trips, climb to GraphQL. If you are wiring into a system you do not own and need to react to its events, you do not poll, you receive webhooks. If the server has to push continuously into a browser, open a WebSocket. If two clients need a direct low latency link for media or data, build it with WebRTC. And if you are integrating with a bank, a hospital, or a government, you will probably speak SOAP, because there the contract outranks your preferences.

StyleReach for it whenThe cost you acceptSeen in
RESTA domain modelled as resources, read and written by clientsRigid shape, over fetching, extra round tripsMost public web APIs
SOAPRegulated, high trust integration across organizationsHeavy, verbose, slow to build againstBanking, healthcare, government
gRPCTraffic between your own services, where speed is moneyBinary, needs codegen, no plain browser supportInternal service meshes
GraphQLVaried clients want varied slices of one rich graphServer complexity, harder caching, query limitsProduct platforms with many clients
WebhooksReact to events in a system you do not controlPublic endpoint, signatures, idempotency, retriesPayments, repo events, order flows
WebSocketsThe server must push continuously to a browserStateful, harder to scale, fragile on mobileChat, live dashboards, trading
WebRTCDirect low latency media or data between two clientsComplex setup, relay costs, scaling limitsVideo calls, voice, peer transfer

The seven names are not a menu you order from by mood. They are the field's accumulated answers to a few plain questions about who talks, when, in what shape, through whom, and at what cost. Most arguments about which API style is best are really arguments about which problem you are solving, conducted by people who have not noticed they disagree about that first.

Learn the questions. The names will pick themselves.