Conditional GET — un mecanismo HTTP que permite a un cliente verificar la relevancia de un recurso en caché antes de una descarga completa. El cliente envía una solicitud GET con los encabezados If-None-Match (que contiene ETag) o If-Modified-Since (que contiene una fecha), y el servidor devuelve 304 Not Modified sin cuerpo de respuesta si el recurso no ha cambiado. Según MDN Web Docs, 2025, las solicitudes condicionales reducen el tráfico de red de servidores y clientes. 304 Not Modified es un estado HTTP clave para la sincronización eficiente de aplicaciones móviles.
Lo más importante
Conditional GET es una solicitud GET que incluye uno o más encabezados condicionales, basados en los cuales el servidor decide si devolver una respuesta completa o solo el estado 304 Not Modified. El objetivo principal es evitar transmitir el cuerpo de la respuesta si el recurso no ha cambiado desde la última solicitud. Este es un mecanismo fundamental de caché HTTP definido en RFC 7232.
Para las aplicaciones móviles, Conditional GET es una de las formas más efectivas de optimizar el tráfico de red. Un escenario típico: al abrir una aplicación, el cliente envía una serie de solicitudes GET condicionales para cargar el feed, el perfil y la configuración. Si los datos no han cambiado, la aplicación recibe 304 y usa la copia local. Esto toma milisegundos en lugar de segundos y no consume datos móviles.
Según Google Web Fundamentals (2025), la implementación de solicitudes GET condicionales en una aplicación móvil reduce el tiempo de carga promedio en un 40–60% para visitas repetidas y reduce el uso de tráfico en un 70–90% para páginas con actualizaciones poco frecuentes. El efecto es especialmente notable en conexiones lentas (3G, Edge), donde cada byte cuenta.
El proceso consta de tres pasos. Primero — el cliente envía una solicitud GET normal, el servidor devuelve el recurso junto con los encabezados de caché (ETag, Last-Modified). Segundo — el cliente guarda el recurso y sus validadores localmente. Tercero — en una solicitud repetida, el cliente envía un GET con If-None-Match (para ETag) y/o If-Modified-Since (para Last-Modified). El servidor verifica los validadores y responde 304 si el recurso no ha cambiado, o 200 con nuevos datos.
El servidor utiliza prioridad de ETag sobre Last-Modified cuando ambos encabezados están presentes. Esto se debe a que ETag proporciona una validación más precisa — el hash del contenido cambia con cualquier modificación, mientras que Last-Modified tiene una resolución de un segundo. Si el ETag coincide, el servidor devuelve inmediatamente 304 sin verificar Last-Modified.
Ejemplo de un ciclo completo de Conditional GET en una secuencia de solicitudes:
// Paso 1: Primera solicitud — obtener datos y ETag
GET /api/profile
Response: 200 OK
ETag: "33a64df551425fcc55e"
Body: { "name": "Alice" }
// Paso 2: Repetir solicitud — con If-None-Match
GET /api/profile
If-None-Match: "33a64df551425fcc55e"
Response: 304 Not Modified
// El cuerpo de la respuesta está ausente — usar copia local
En la segunda solicitud, el servidor compara el ETag de If-None-Match con el hash actual del recurso. Si coinciden, devuelve 304 sin cuerpo — el cliente continúa usando los datos en caché. Esta es la esencia de Conditional GET: tráfico mínimo con la máxima relevancia de los datos.
Una solicitud GET normal siempre devuelve una respuesta completa 200 OK con cuerpo. Incluso si el recurso no ha cambiado, el servidor transmite todos los datos nuevamente. Esto es aceptable para recursos pequeños o solicitudes poco frecuentes, pero para aplicaciones móviles con cientos de solicitudes en cada inicio, este enfoque conduce a un consumo excesivo de tráfico y batería.
Conditional GET agrega una sobrecarga en forma de encabezados (generalmente 50–200 bytes por solicitud) pero ahorra kilobytes y megabytes con una respuesta 304. Cuanto más grande es el recurso, más beneficiosa es la solicitud condicional. Para imágenes, listas de datos y documentos JSON desde 10 KB, Conditional GET se amortiza desde la primera solicitud repetida.
Características comparativas de los dos enfoques:
| Parámetro | GET normal | Conditional GET |
|---|---|---|
| Tráfico (sin cambios) | Respuesta completa | Solo encabezados (~200 bytes) |
| Latencia | Descarga completa | Milisegundos (304) |
| Carga del servidor | Generación + transferencia | Solo verificación de ETag |
| Complejidad de implementación | Mínima | Requiere almacenamiento de ETag |
| Eficiencia para datos grandes | Baja | Alta |
Veamos una implementación completa de Conditional GET en Kotlin usando OkHttp y Room para almacenar ETag. Una aplicación de lista de tareas carga tareas desde el servidor y usa solicitudes condicionales para minimizar el tráfico. Los ETags se almacenan en una base de datos local para persistir entre sesiones.
Repositorio con Conditional GET en Kotlin:
class TaskRepository(
private val api: TaskApi,
private val etagDao: EtagDao
) {
suspend fun getTasks(): List<Task> {
val savedEtag = etagDao.getEtag("tasks")
val response = api.fetchTasks(
ifNoneMatch = savedEtag
)
return when (response.code()) {
304 -> taskDao.getAll() // desde caché local
200 -> {
response.header("ETag")?.let {
etagDao.saveEtag("tasks", it)
}
val tasks = response.body() ?: emptyList()
taskDao.replaceAll(tasks)
tasks
}
else -> throw Exception(
"Sync failed: ${response.code()}")
}
}
}
TaskRepository verifica el código de respuesta: 304 significa que no hay cambios, y los datos se devuelven desde la caché local de Room. En 200, se guarda un nuevo ETag y las tareas se actualizan en la base de datos local. Este patrón es un estándar para aplicaciones móviles con sincronización mediante API REST.
Conditional GET se utiliza ampliamente en aplicaciones móviles para optimizar la sincronización de datos. Escenarios principales: carga de feeds de noticias (Twitter, Instagram consultan periódicamente la API con If-None-Match), actualización de perfiles de usuario, carga de listas de notificaciones y sincronización de tareas. En cada caso, la aplicación puede verificar la relevancia de los datos sin descargarlos nuevamente.
Para aplicaciones offline-first, Conditional GET sirve como la primera etapa de sincronización. La aplicación primero envía solicitudes GET condicionales para todos los recursos que se han modificado localmente desde la última sincronización. Los recursos con 304 no requieren descarga. Después de eso, la aplicación envía PUT/POST para los cambios locales. Este enfoque de dos fases garantiza un consumo mínimo de tráfico.
En combinación con Resolución de Conflictos, Conditional GET permite detectar conflictos de manera eficiente. Si el cliente recibe 200 con nuevos datos (el recurso ha cambiado) pero tiene cambios locales no enviados — se registra un conflicto. El cliente puede aplicar LWW (los cambios locales se pierden) o iniciar una estrategia de fusión para combinar los cambios locales y remotos. Según Meta Engineering Blog (2025), la implementación de Conditional GET en Messenger redujo el tráfico de sincronización promedio en un 73%.
Preguntas frecuentes
Conditional GET — una solicitud HTTP GET con encabezados condicionales (If-None-Match, If-Modified-Since). El servidor devuelve 304 Not Modified si el recurso no ha cambiado, o 200 con nuevos datos. Es un mecanismo de caché eficiente.
Un GET normal siempre devuelve una respuesta completa con cuerpo. Conditional GET agrega encabezados de verificación de versión (ETag, fecha). Si los datos no han cambiado, el servidor responde 304 sin cuerpo, ahorrando tráfico y tiempo de carga.
Para un almacenamiento en caché efectivo, guarde ETag y Last-Modified de cada respuesta del servidor en una base de datos local. En la siguiente solicitud, envíelos en los encabezados If-None-Match e If-Modified-Since. En 304, use los datos de la caché local.
En una respuesta 304, el servidor no transmite el cuerpo de la respuesta — solo los encabezados (~200 bytes). Para un recurso de 50 KB, esto significa un ahorro de tráfico del 99.6%. Para una aplicación que se sincroniza 50 veces al día, los ahorros alcanzan decenas de megabytes por mes.
Sí, es el enfoque estándar para la sincronización delta. El cliente verifica la relevancia de cada recurso mediante Conditional GET, descarga solo los que han cambiado y envía los cambios locales. Este enfoque se utiliza en Twitter, Instagram, Telegram y la mayoría de las API modernas.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.