REST vs GraphQL para un cliente móvil: ¿qué cambia realmente para ti como ingeniero móvil?
No es un debate de sintaxis: REST y GraphQL trasladan compromisos completamente distintos al cacheo, el soporte offline y cuántas idas y vueltas necesita tu pantalla.
APRENDE HACIENDOPon a prueba tu intuición3 pasos
REST vs GraphQL para un cliente móvil: ¿qué cambia realmente para ti como ingeniero móvil?
Usa los ejemplos y la explicación de la lección para comprobar tu idea.
Reflexión personal. No se envía a ningún servicio de IA.#La trampa de esta pregunta
La mayoría responde con la frase de manual: 'GraphQL soluciona el over-fetching y el under-fetching'. Es cierto, pero no es lo primero que debería decir un ingeniero móvil senior. La conversación real es sobre qué le pasa al cacheo de tu app, a tu estrategia offline y a la complejidad del cliente una vez que eliges una de las dos tecnologías — porque ambas redistribuyen la misma complejidad total, solo la mueven de lugar.
#Dónde ocurren realmente los round trips
Imagina una pantalla de perfil que necesita: los datos básicos del usuario, sus últimos 10 posts y su número de seguidores. Con una API REST diseñada alrededor de recursos, eso suele ser tres endpoints separados, y si el endpoint de posts necesita primero el ID del usuario, tienes una cascada — una petición debe terminar antes de que la siguiente pueda empezar.
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)// las dos llamadas siguientes pueden ejecutarse en paralelo una vez que tenemos el idval posts = coroutineScope { async { api.getPosts(userId) } }val followers = coroutineScope { async { api.getFollowerCount(userId) } }return ProfileScreenState(user, posts.await(), followers.await())}
Puedes paralelizar las dos últimas llamadas, pero igual pagas el presupuesto de latencia de tres round trips con terminación TLS sobre una conexión celular, y estás transportando todos los campos que cada endpoint decidió incluir — incluso los que esta pantalla ni siquiera renderiza.
Un cliente GraphQL colapsa todo eso en una sola petición que nombra exactamente los campos que la pantalla necesita:
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) }
Un solo round trip, sin bytes desperdiciados, sin cascada. En una buena conexión Wi-Fi la diferencia es invisible. En una conexión 3G inestable en el campo, tres round trips contra uno es la diferencia entre una pantalla que pinta en 400ms y una que gira durante cuatro segundos.
#Lo que pagas a cambio
Esta es la parte que el entrevistador realmente quiere escuchar. GraphQL normalmente corre sobre un único endpoint POST, lo que significa que la infraestructura HTTP que REST te regalaba — cacheo por URL, cacheo en el edge de una CDN, ETags asociados a un recurso — deja de funcionar en gran medida. No puedes cachear /graphql como cacheas /users/42, porque la URL siempre es la misma y lo relevante está en el cuerpo de la petición.
Para recuperar el cacheo, clientes GraphQL como Apollo Kotlin y Relay traen una caché normalizada: cada objeto se aplana por su id y __typename, y luego las queries se resuelven primero contra ese almacén local. Es poderoso — actualizar un objeto actualiza todas las queries que lo referenciaban — pero es maquinaria real del lado del cliente que ahora te pertenece y debes razonar, frente a una caché en disco de OkHttp que se administra casi sola.
El otro compromiso que vale la pena nombrar es la evolución del esquema. Agregar un campo a un tipo GraphQL no rompe nada, así que backend y mobile pueden lanzar de forma independiente sin subir de versión la API. Las APIs REST suelen resolver el mismo problema con endpoints versionados o cambios aditivos cuidadosos, lo cual funciona pero exige más disciplina entre equipos.
🧠 Check your understanding
0/1 · 0/1 answered1. ¿Por qué una API GraphQL suele perder el cacheo HTTP gratuito que REST obtiene de CDNs y navegadores?
🧠 Check your understanding
0/1 · 0/1 answered1. Un equipo móvil construye una app CRUD simple de lista de tareas con cinco endpoints y ninguna pantalla que agregue más de un recurso. ¿Cuál es el argumento más fuerte para quedarse en REST?