Reference Guide · APIs

REST, GraphQL or RPC — Choosing an API Style

The choice between REST, GraphQL and RPC is often made by fashion and rarely by fit. Which style belongs to which shape of problem, what each one hides, and why the simplest one is usually enough. A decision document for CTOs, architects and API developers.

What is this? · Reference Guide

A solid guide to an engineering question — with trade-offs, costs and the case in which we decide differently. Not an opinion piece, but a reference text. Go to overview

Author
Batunet Engineering
Reading time
16 min
Level
In depth
Status
Approved
Last reviewed
21 July 2026
Updated
21 July 2026
On this page

Few API decisions are judged as much by the zeitgeist as the choice of style. Sometimes one is considered modern and the other outdated, then the fashion reverses again — and in both cases a question of fit is argued as a question of taste. Yet REST, GraphQL and RPC do not name a level of quality, but three different ways in which two systems talk to each other. The useful question is not which style is better, but what shape a problem has and which style fits that shape.

This document treats the three styles as what they are: tools with different shapes, each strong for certain problems and weak for others. It is deliberately protocol- and product-neutral and presupposes the principles of long-lived API design covered elsewhere — contracts, compatibility, trust boundaries. Here, the sole concern is the preceding decision of which style to shape that contract in at all. No numbers are given.

1. The wrong question

"Which API style is best?" is the wrong question, because it expects a general answer where only situational ones exist. Each of the three styles is the right choice for some problems and a detour for others. Whoever searches for the best style is having a fashion argument; whoever searches for the fitting one is asking the useful question: what does the communication that is supposed to happen here look like — who calls whom, how often, and for what?

The reason the choice of style matters at all lies in its longevity. The style shapes the form of the contract between systems, and that contract, like every interface, is hard to change once others rely on it. So it is best to choose the style deliberately and for a reason, not out of habit or fashion — because you will live with it for a long time. The question before choosing a style is always the question about the problem.

To make matters worse, a style once chosen is hard to switch. Because it shapes the contract that external systems rely on, switching styles carries the same burden as any deep change to an interface — you cannot do it unilaterally without touching the callers. That raises the stakes of the original choice: it is not one you make casually and correct easily later, but one you carry for a long time. All the more reason to make it deliberately and for a reason you can name.

Trade-off. Asking about fit instead of the best style means giving up the convenience of a general recommendation and judging for your own system.

Cost. The judgment requires understanding your own communication shape precisely before choosing the style — more work than reaching for the familiar.

When we decide differently. Where a team has deep mastery of one style and the problem fits its shape, the long deliberation is unnecessary; familiarity then rightly tips the balance.

2. What really distinguishes the three styles

The three styles differ in what the communication revolves around. REST revolves around resources: named things that you retrieve and modify through a small, fixed set of operations. Its model is the structure of the web itself, and its strength is simplicity and ubiquity — almost everyone knows it, almost everything supports it. RPC revolves around actions: you call a named function in a foreign system as if it were your own. Its strength is directness — where the point is executing operations, calling a function is the most natural form.

GraphQL revolves around queries: the caller describes exactly which data it wants and gets exactly that back, in one request, even across many connected things. Its strength is flexibility on the caller's side — it fetches in one go what it would otherwise have to assemble across many calls. These three shapes are not better or worse, just different: retrieving resources, executing actions, querying data flexibly. The question is which of these shapes your own communication has.

In practice, the boundaries between the styles are less sharp than the names suggest. You can add a few action-like calls to a resource-oriented interface without betraying the style; you can put a flexible query layer over an otherwise plain interface where it is genuinely needed. The three styles are tendencies, not prisons — and the mistake is not mixing them but confusing them: expressing a communication in a shape that does not match it, just because you committed to one style.

StyleRevolves aroundStrengthNaturally weak at
RESTresources (things)simplicity, ubiquitymany connected queries in one go
RPCactions (functions)directness when executingretrieving and linking data
GraphQLqueries (desired data)flexibility for the callersimplicity, operations, caching

Trade-off. Taking shape seriously means choosing the style by the kind of communication instead of forcing one style onto every communication.

Cost. Close examination costs time and an honest analysis of what really flows between the systems.

When we decide differently. Where a system contains several communication shapes, it can be right to choose different styles for different parts instead of squeezing the whole into one.

3. When REST is enough — which is often

The most common case is also the most unremarkable: for most systems, REST is enough, and simplicity is a value you do not give up lightly. Where communication essentially consists of retrieving and modifying named things — and that applies to a large share of business software — REST is the obvious, widespread and calm choice. It is understood everywhere, supported everywhere, easy to cache and easy to operate. Its plainness is not a flaw but the reason it holds up for years.

Communication? which shape? retrieve/change things → REST execute an action → RPC flexible, connected queries → GraphQL

Diagram: no style is the starting point. You ask about the shape of the communication — things, actions or flexible queries — and choose accordingly. For the broad middle, the shape is "things," and that is where REST wins.

A concrete, often underestimated advantage of REST is caching. Because retrieving a named thing is a clear, repeatable request, its response can be cached along the way between provider and caller — in many places, with the proven tools of the web. That relieves the source and speeds up the caller without the system having to do anything special. Richer styles, whose requests are less predictable, give up a good part of this advantage — a quiet price that only shows under load and is easily overlooked when comparing styles.

The temptation to choose a richer style instead of plain REST is strong because it looks more modern — but where REST solves the problem, a richer style is not progress but a complication. You trade a solution that everyone understands and that is effortless to operate for one that can do more than you need and demands more effort, more operations and more knowledge in return. Giving up simplicity where it is enough is rarely a good bet.

Trade-off. Choosing REST buys simplicity, ubiquity and calm operations at the cost of forgoing the particular flexibility or directness of the other styles.

Cost. Where the communication does have the shape of another style, you have to emulate it in REST somewhat more awkwardly — the price of plainness.

When we decide differently. Where the communication clearly has the shape of actions or of flexible, connected queries, REST is the detour, and the fitting style is the better choice.

4. When GraphQL fits — and what it costs

GraphQL is the right choice where flexibility on the caller's side has real value: where many different callers need very different slices of the same, heavily connected data, and where assembling those slices across many individual calls would be expensive or cumbersome. That is where GraphQL plays to its strength — the caller describes its need, and the system delivers exactly that, in one go.

Caller assembling many requests Caller exactly that one flexible query

Diagram: where a caller would otherwise assemble many connected things one by one, a flexible query fetches exactly what is wanted in one go — that is GraphQL's case, and only there is its price worth paying.

This flexibility has a price that is easily overlooked at the moment of choosing. The caller's freedom shifts complexity to the provider's side: requests are harder to predict, harder to cache and harder to secure against abuse, because you no longer know what the caller will ask for. Operations become more demanding, and the system needs safeguards that REST does not. GraphQL is therefore not a replacement for REST, but the right choice for one particular case — diverse data needs across connected data — and an expensive detour for all others.

Trade-off. GraphQL buys flexibility for the caller with shifted complexity, harder caching and more demanding operations on the provider's side.

Cost. The freedom of the query requires additional safeguards against unpredictability and abuse, which you build and maintain.

When we decide differently. Where data needs are simple and predictable, GraphQL's flexibility goes unused and you carry only its price — then the plainer style is superior.

5. When RPC is the clearest form

RPC is the right choice where the communication essentially consists of executing actions, not retrieving things. Where one system asks another to do something — kick off a calculation, trigger a process, carry out an operation — directly calling a named function is the most honest form. You do not have to translate the action into the language of resources, where it reads unnaturally, but name it for what it is. Especially in communication between services of the same system, where directness and efficiency count and no outside audience is served, RPC is often the plainest and clearest choice — there, its tighter coupling weighs little, because the services involved belong together anyway and evolve together.

The price of RPC is the flip side of its directness. Because it binds more closely to the called function, the coupling between systems tends to be tighter, and the style is less self-explanatory for outside callers than ubiquitous REST. For a public, widely used interface, that is a drawback; for internal communication between services that belong together, the tighter coupling is often irrelevant and the directness a gain. As with the other styles, context decides: RPC shines where actions are front and center and the callers are known.

InterfaceCallersLeans toward
public, widely usedmany, unknownREST — ubiquity, self-explanation
internal, between servicesknown, belonging togetherRPC — directness when executing
data-rich, many viewsmany, with varied needsGraphQL — query flexibility

Trade-off. RPC buys directness in executing actions with tendentially tighter coupling and less self-explanation for outside callers.

Cost. The closer binding to the called function can make changes to the interface more noticeable, especially when the callers are not closely coordinated.

When we decide differently. For a public interface with many unknown callers, the ubiquity and self-explanation of REST are usually more valuable than the directness of RPC.

6. The criterion: the shape of the communication

All three paths converge on a single criterion: the shape of the communication that is supposed to take place. If everything revolves around named things that you retrieve and change, REST is the natural choice. If it is about executing actions between known systems, RPC is the clearest form. If many different callers need flexible slices of heavily connected data, GraphQL has the edge. The criterion is not fashion, but the question of who addresses whom, how and for what.

The shape of the communication is joined by a second, often underestimated factor: what the team masters and what its callers expect. A style many people know lowers the cost of operating a system for years and of having outside developers use its interface. A richer, rarer style demands more knowledge on both sides — from the provider who operates it and from the caller who uses it. These knowledge costs are real and lasting, and when in doubt they argue for the widespread style, unless the shape of the problem clearly demands another.

Lifespan sharpens this criterion with a note of caution: because the style shapes the contract and the contract is hard to change, when in doubt you choose the simpler, more widespread style that will still be understood and staffable in ten years. A richer style has to justify its extra effort over the lifespan; if it does not, plainness is the longer-lived choice. Whoever decides by the shape of the communication and the lifespan needs neither to defend the style against fashion nor to follow it — they decide on the merits.

Trade-off. Deciding by the shape of the communication requires naming that shape honestly instead of following the familiar or fashionable style.

Cost. The criterion forces a differentiated answer per interface instead of a convenient house rule for everything.

When we decide differently. Where an external requirement dictates the style — a required compatibility, an existing landscape — the criterion steps back, and you follow the requirement.

7. Common mistakes

The recurring patterns in which the choice of style fails — almost all of them variations of deciding by fashion instead of shape:

  • Choosing the style by the zeitgeist and arguing a question of fit as a question of taste.
  • Considering REST outdated and choosing a richer style where plainness would have been enough.
  • Choosing GraphQL's flexibility without the diverse data needs that justify it — and carrying only its price.
  • Overlooking GraphQL's shifted complexity: harder caching, more demanding operations, safeguards against unpredictability.
  • Forcing actions into the language of resources where a direct call would have been the more honest form.
  • Choosing RPC for a public interface with many unknown callers, where ubiquity and self-explanation count for more.
  • Squeezing the whole system into one style although different parts have different communication shapes.
  • Overlooking the style's longevity and choosing one that will be hard to understand or staff in years to come.

8. Decision checklist

To be clarified in order before choosing an API style:

  • Shape of the communication? Does everything revolve around things (REST), actions (RPC) or flexible queries of connected data (GraphQL)?
  • Is REST enough? Does the plainest, most widespread style solve the problem — and is a richer style really necessary?
  • Flexibility needed? For GraphQL: are there many callers with very different needs for connected data — or will the flexibility go unused?
  • Hidden costs considered? Have the harder caching and more demanding operations of GraphQL, or the tighter coupling of RPC, been factored in?
  • Public or internal? Does the interface serve many unknown callers (rather REST) or known services that belong together (RPC defensible)?
  • Mixed system? Has it been checked whether different parts deserve different styles instead of one for everything?
  • Longevity? Is the style one that can be understood and staffed for years — and does a richer one justify its extra effort?

Whoever can answer these questions has chosen the API style by the shape of the communication — not by what currently counts as modern.

FAQ

Is GraphQL the modern successor to REST? No, it is a different shape for a different case. GraphQL shines where many callers need flexible slices of heavily connected data; REST shines where the point is plainly retrieving and changing named things. One does not replace the other — they fit different shapes of communication. For the most common case, REST is enough.

Why is REST the right choice for most systems? Because most business communication essentially consists of retrieving and modifying named things — exactly REST's shape. REST is understood everywhere, easy to cache and easy to operate. Its plainness is not a flaw but the reason it holds up for years. Where it is enough, a richer style is a complication.

What does GraphQL cost that is easily overlooked? The caller's flexibility shifts complexity to the provider: requests are harder to predict, harder to cache and harder to secure against abuse. Operations become more demanding. These costs are well spent where diverse data needs justify them, and wasted where they are absent.

When is RPC the right choice? Where the communication consists of executing actions, not retrieving things — especially between services of the same system, where directness counts and no outside audience is served. Expressing an action as a named function call is more honest than forcing it into the language of resources. For public interfaces, REST is usually the better choice.

Can we use several styles in one system? Yes, and often that is right. Different parts of a system have different communication shapes — internal services talk to each other differently than a public interface talks to its callers. Squeezing the whole system into one style because one part needs it imposes on the other parts a shape that is not theirs.

How do I choose for a long-lived system? When in doubt, the simpler, more widespread style that will still be understood and staffable in ten years. Because the style shapes the hard-to-change contract, a richer style must justify its extra effort over the lifespan. If it does not, plainness is the longer-lived choice.

Further reading

It is grounded in the Batunet Engineering Method: decide by the shape of the communication, choose the plainest thing that holds up, follow the need instead of fashion.

Closing engineering principle

The API style is not a creed but an adaptation to the shape of the communication. REST, GraphQL and RPC are three answers to three different questions — retrieving things, executing actions, querying data flexibly — and the art lies in recognizing your own question before choosing the answer. For the broad middle of business systems, the question is "retrieve and change things," and there the plain, widespread answer is also the longest-lived. The temptation to choose a richer style because it looks more modern is the same temptation you resist with technology in general: you do not choose the most exciting option but the most fitting — and the most fitting is plain more often than the zeitgeist would have you believe. Whoever chooses the style by the shape of the communication and the lifespan has an interface that still holds up and is still understood long after the fashions that would otherwise have dictated it have changed.


No API style is modern or outdated — each is the answer to a particular shape of question. Whoever knows their own question has no need for fashion.

Referenced entities

Knowledge graph

Continue your engineering journey.

Related concepts, decisions, playbooks and perspectives — as one connected path, not a list of links.

A concrete project in this field?

Reference Guides show how we think. For your system, talk to our management — technical, no sales pitch.