REST vs GraphQL for a mobile client — what actually changes for you as a mobile engineer?
It's not a syntax debate — REST and GraphQL push completely different tradeoffs onto caching, offline support, and how many round trips your screen needs.
LEARN BY DOINGPut your intuition to work3 steps
REST vs GraphQL for a mobile client — what actually changes for you as a mobile engineer?
Use the lesson’s examples and explanation to check your idea.
Personal reflection. Nothing is sent to an AI service.#The trap in this question
Most candidates answer with the textbook line: "GraphQL fixes over-fetching and under-fetching." That's true, but it's not what a senior mobile engineer should lead with. The real conversation is about what happens to your app's caching, your offline story, and your client-side complexity once you pick one — because both technologies redistribute the same total complexity, they just move it to different places.
#Where the round trips actually happen
Picture a profile screen that needs: the user's basic info, their last 10 posts, and their follower count. With a REST API designed around resources, that's often three separate endpoints, and if the posts endpoint needs the user ID first, you get a waterfall — one request has to finish before the next can start.
interface ProfileApi {@GET("/users/{id}")suspend fun getUser(@Path("id") id: String): UserDto@GET("/users/{id}/posts")suspend fun getPosts(@Path("id") id: String): List<PostDto>@GET("/users/{id}/followers/count")suspend fun getFollowerCount(@Path("id") id: String): FollowerCountDto}suspend fun loadProfile(api: ProfileApi, userId: String): ProfileScreenState {val user = api.getUser(userId)// two independent calls can run concurrently once we have the idval posts = coroutineScope { async { api.getPosts(userId) } }val followers = coroutineScope { async { api.getFollowerCount(userId) } }return ProfileScreenState(user, posts.await(), followers.await())}
You can parallelize the last two calls, but you still pay three TLS-terminated round trips' worth of latency budget on a cellular connection, and you're shipping whatever fields each endpoint decided to include — even the ones this screen doesn't render.
A GraphQL client collapses that into one request that names exactly the fields the screen needs:
query ProfileScreen($userId: ID!) {user(id: $userId) {nameavatarUrlposts(first: 10) {idcaptionthumbnailUrl}followerCount}}
val response = apolloClient.query(ProfileScreenQuery(userId)).execute()val state = response.data?.user?.let { ProfileScreenState.from(it) }
One round trip, no wasted bytes, no waterfall. On a good Wi-Fi connection the difference is invisible. On a flaky 3G connection in the field, three round trips versus one is the difference between a screen that paints in 400ms and one that spins for four seconds.
#What you pay for it
This is the part interviewers actually want to hear. GraphQL typically runs over a single POST endpoint, which means the HTTP infrastructure you got for free with REST — per-URL caching, CDN edge caching, ETags keyed to a resource — mostly stops working. You can't cache /graphql the way you cache /users/42, because the URL is always the same and the meaningful part is in the request body.
To get caching back, GraphQL clients like Apollo Kotlin and Relay ship a normalized cache: every object is flattened by its id and __typename, then queries are resolved against that local store first. It's powerful — updating one object updates every query that referenced it — but it's real client-side machinery you now own and have to reason about, versus an OkHttp disk cache that mostly manages itself.
The other tradeoff worth naming: schema evolution. Adding a field to a GraphQL type is non-breaking, so backend and mobile teams can ship independently without an API version bump. REST APIs usually solve the same problem with versioned endpoints or careful additive changes, which works but requires more discipline across teams.
🧠 Check your understanding
0/1 · 0/1 answered1. Why does a GraphQL API typically lose the free HTTP caching that REST gets from CDNs and browsers?
🧠 Check your understanding
0/1 · 0/1 answered1. A mobile team is building a simple todo-list CRUD app with five endpoints and no screen that aggregates more than one resource. What's the strongest argument for staying on REST?