Architecture

Building Mobile-Friendly APIs: What Backend Engineers Get Wrong

Back to Blog

The Problem: APIs Built for the Browser

Most backend engineers build APIs with web clients in mind. That makes sense. The web was there first. But mobile is not a smaller browser. It is a fundamentally different environment with its own constraints.

A phone on a cellular network deals with high latency, limited bandwidth, and a battery that drains with every network call. Users switch between WiFi and LTE mid-request. They walk into elevators. They close the app and reopen it thirty seconds later expecting the same state.

When your API ignores these realities, mobile engineers end up writing layers of workaround code on the client. That means more bugs, slower releases, and frustrated teams on both sides. Here is what we have learned building APIs that mobile engineers actually want to consume.

Payload Size Matters More Than You Think

On a web app running over fiber, an extra 50KB in a JSON response is invisible. On a phone over 3G in a parking garage, it is the difference between a snappy experience and a loading spinner.

Every byte costs battery. The radio on a phone powers up for each network request and stays active for a cooldown period after. Larger payloads keep the radio on longer. Multiply that across dozens of API calls and you are measurably draining the user's battery.

Pagination Done Right: Cursor-Based, Not Offset

Offset-based pagination breaks on mobile. A user scrolls through a feed, the dataset shifts underneath them, and suddenly they see duplicate items or miss entries entirely. This is not a theoretical problem. It happens constantly in production.

Cursor-based pagination solves this. Instead of saying "give me page 5," the client says "give me the next 20 items after this cursor." The cursor is an opaque token that points to a stable position in the dataset.

A good pagination response includes three things: the data array, a next cursor, and a has_more flag. Nothing else is needed.

Error Responses Mobile Clients Can Actually Parse

Returning a raw 500 with an HTML error page is not helpful to a mobile client trying to show a toast message. Mobile apps need structured, predictable error responses they can parse programmatically and present to the user in context.

Every error response should follow the same shape. We use a simple structure across all our projects:

Mobile engineers should never have to regex-match an error message to figure out what went wrong.

Versioning That Does Not Break Old App Versions

Web apps deploy instantly. You push a change and every user gets it. Mobile apps do not work that way. Users on version 2.1 of your app might not update for months. Some never will. Your API has to support them all.

We version APIs in the URL path: /v1/users, /v2/users. It is explicit and impossible to miss. Header-based versioning sounds elegant but causes debugging nightmares when someone forgets to set the right header.

Caching Headers and ETags for Mobile

Mobile networks are unreliable. Good caching turns your API from unusable to resilient. Every response should include proper Cache-Control headers and ETags.

With ETags, a mobile client can make a conditional request. If the data has not changed, the server returns a 304 Not Modified with no body. That saves bandwidth, battery, and time. For data that changes infrequently, like user profiles or app configuration, this is a massive win.

GraphQL vs REST for Mobile: A Practical Take

GraphQL lets mobile clients request exactly the data they need. No over-fetching. No under-fetching. In theory, it is perfect for mobile. In practice, it depends.

GraphQL shines when your mobile app has many screens with different data requirements hitting the same underlying models. Instead of building dozens of bespoke REST endpoints, you expose a graph and let the client query what it needs.

REST wins when your API surface is small and well-defined. It is simpler to cache at the HTTP layer. It is easier to monitor and rate-limit. The tooling is more mature.

Pick the tool that matches your team and your problem. Do not pick GraphQL because it is trendy. Do not avoid it because it is unfamiliar.

In our projects, we often use REST for straightforward CRUD operations and introduce GraphQL selectively for screens that aggregate data from multiple sources. Pragmatism beats purity.

Build APIs With Mobile in Mind From Day One

Retrofitting mobile-friendliness into an existing API is painful and expensive. The best time to think about payload size, pagination, caching, and versioning is before you write the first endpoint.

If you are building a product that will have a mobile client, involve a mobile engineer in your API design review. They will catch problems that backend engineers simply do not think about.

We design APIs this way at DEVSFLOW because we build both sides. Our backend and mobile teams sit in the same room and review the same contracts. That is the difference between an API that works and one that works well on a phone in a subway tunnel.

Tell us about your project and we will walk you through how we would design the API layer for your mobile app.

Ali Assad

Ali Assad

Full Stack Engineer at DEVSFLOW Technologies