Conditional GET — bir istemcinin tam indirmeden önce önbelleğe alınmış bir kaynağın güncelliğini kontrol etmesini sağlayan bir HTTP mekanizmasıdır. İstemci, If-None-Match (ETag içerir) veya If-Modified-Since (tarih içerir) başlıklarıyla birlikte bir GET isteği gönderir ve kaynak değişmemişse sunucu yanıt gövdesi olmadan 304 Not Modified döndürür. MDN Web Docs, 2025'e göre, koşullu istekler sunucu ve istemci ağ trafiğini azaltır. 304 Not Modified, verimli mobil uygulama senkronizasyonu için önemli bir HTTP durumudur.
Ana Hatlar
Conditional GET, bir veya daha fazla koşullu başlık içeren bir GET isteğidir; sunucu bunlara dayanarak tam bir yanıt mı yoksa yalnızca 304 Not Modified durumunu mu döndüreceğine karar verir. Ana hedef, kaynak son istekten bu yana değişmemişse yanıt gövdesinin iletilmesini önlemektir. Bu, RFC 7232'de tanımlanan temel bir HTTP önbellekleme mekanizmasıdır.
Mobil uygulamalar için Conditional GET, ağ trafiğini optimize etmenin en etkili yollarından biridir. Tipik bir senaryo: uygulama açıldığında, istemci feed'i, profili ve ayarları yüklemek için bir dizi koşullu GET isteği gönderir. Veriler değişmemişse, uygulama 304 alır ve yerel kopyayı kullanır. Bu, saniyeler yerine milisaniyeler sürer ve mobil veri tüketmez.
Google Web Fundamentals'a (2025) göre, bir mobil uygulamada koşullu GET isteklerinin uygulanması, tekrarlanan ziyaretler için ortalama yükleme süresini %40–60 oranında azaltır ve seyrek güncellenen sayfalar için trafik kullanımını %70–90 oranında düşürür. Etki, her baytın önemli olduğu yavaş bağlantılarda (3G, Edge) özellikle belirgindir.
Süreç üç adımdan oluşur. Birinci — istemci normal bir GET isteği gönderir, sunucu önbellek başlıklarıyla (ETag, Last-Modified) birlikte kaynağı döndürür. İkinci — istemci kaynağı ve doğrulayıcılarını yerel olarak kaydeder. Üçüncü — tekrarlanan bir istekte, istemci If-None-Match (ETag için) ve/veya If-Modified-Since (Last-Modified için) ile bir GET gönderir. Sunucu doğrulayıcıları kontrol eder ve kaynak değişmemişse 304, yeni veri varsa 200 ile yanıt verir.
Sunucu, her iki başlık da mevcut olduğunda ETag'e Last-Modified'a göre öncelik verir. Bunun nedeni, ETag'in daha hassas doğrulama sağlamasıdır — içerik karması herhangi bir değişiklikle değişirken, Last-Modified bir saniyelik çözünürlüğe sahiptir. ETag eşleşirse, sunucu Last-Modified'ı kontrol etmeden hemen 304 döndürür.
İstek dizisinde tam bir Conditional GET döngüsü örneği:
// Adım 1: İlk istek — verileri ve ETag'i al
GET /api/profile
Response: 200 OK
ETag: "33a64df551425fcc55e"
Body: { "name": "Alice" }
// Adım 2: İsteği tekrarla — If-None-Match ile
GET /api/profile
If-None-Match: "33a64df551425fcc55e"
Response: 304 Not Modified
// Yanıt gövdesi yok — yerel kopyayı kullan
İkinci istekte, sunucu If-None-Match'ten gelen ETag'i geçerli kaynak karmasıyla karşılaştırır. Eşleşirse, gövdesiz 304 döndürür — istemci önbelleğe alınmış verileri kullanmaya devam eder. Conditional GET'in özü budur: maksimum veri güncelliği ile minimum trafik.
Normal bir GET isteği her zaman gövde içeren tam bir 200 OK yanıtı döndürür. Kaynak değişmemiş olsa bile, sunucu tüm verileri yeniden iletir. Bu, küçük kaynaklar veya seyrek istekler için kabul edilebilir, ancak her başlatmada yüzlerce istek gönderen mobil uygulamalar için bu yaklaşım aşırı trafik ve pil tüketimine yol açar.
Conditional GET, başlıklar biçiminde ek yük ekler (genellikle istek başına 50–200 bayt) ancak 304 yanıtıyla kilobaytlar ve megabaytlar tasarruf sağlar. Kaynak ne kadar büyükse, koşullu istek o kadar avantajlıdır. 10 KB ve üzeri görüntüler, veri listeleri ve JSON belgeleri için Conditional GET, ilk tekrarlanan istekten itibaren kendini amorti eder.
İki yaklaşımın karşılaştırmalı özellikleri:
| Parametre | Normal GET | Conditional GET |
|---|---|---|
| Trafik (değişiklik yok) | Tam yanıt | Yalnızca başlıklar (~200 bayt) |
| Gecikme | Tam indirme | Milisaniyeler (304) |
| Sunucu yükü | Oluşturma + aktarım | Yalnızca ETag kontrolü |
| Uygulama karmaşıklığı | Minimum | ETag depolama gerektirir |
| Büyük veriler için verimlilik | Düşük | Yüksek |
Tam bir uygulamayı inceleyelim — ETag depolama için OkHttp ve Room kullanarak Kotlin'de Conditional GET uygulaması. Bir görev listesi uygulaması, sunucudan görevleri yükler ve trafiği en aza indirmek için koşullu istekler kullanır. ETag'ler, oturumlar arasında kalıcı olması için yerel bir veritabanında depolanır.
Kotlin'de Conditional GET içeren depo:
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() // yerel önbellekten
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 yanıt kodunu kontrol eder: 304 değişiklik olmadığı anlamına gelir ve veriler yerel Room önbelleğinden döndürülür. 200'de, yeni bir ETag kaydedilir ve görevler yerel veritabanında güncellenir. Bu desen, REST API senkronizasyonu olan mobil uygulamalar için bir standarttır.
Conditional GET yaygın olarak kullanılır — mobil uygulamalarda veri senkronizasyonu optimizasyonu için. Ana senaryolar: haber akışlarını yükleme (Twitter, Instagram periyodik olarak If-None-Match ile API'yi sorgular), kullanıcı profillerini güncelleme, bildirim listelerini yükleme ve görevleri senkronize etme. Her durumda, uygulama verileri yeniden indirmeden güncelliğini kontrol edebilir.
Çevrimdışı öncelikli uygulamalar için Conditional GET, senkronizasyonun ilk aşaması olarak hizmet eder. Uygulama önce son senkronizasyondan bu yana yerel olarak değiştirilen tüm kaynaklar için koşullu GET istekleri gönderir. 304 alan kaynaklar indirme gerektirmez. Bundan sonra, uygulama yerel değişiklikler için PUT/POST gönderir. Bu iki aşamalı yaklaşım, minimum trafik tüketimini sağlar.
Çatışma Çözümü ile birleştirildiğinde, Conditional GET verimli çatışma tespiti sağlar. İstemci yeni verilerle 200 alırsa (kaynak değişti) ancak gönderilmemiş yerel değişiklikleri varsa — bir çatışma kaydedilir. İstemci LWW uygulayabilir (yerel değişiklikler kaybolur) veya yerel ve uzak değişiklikleri birleştirmek için Birleştirme Stratejisi başlatabilir. Meta Engineering Blog'a (2025) göre, Messenger'da Conditional GET uygulanması ortalama senkronizasyon trafiğini %73 azaltmıştır.
Sıkça Sorulan Sorular
Conditional GET — koşullu başlıklar (If-None-Match, If-Modified-Since) içeren HTTP GET isteği. Kaynak değişmemişse sunucu 304 Not Modified, yeni veri varsa 200 döndürür. Verimli bir önbellekleme mekanizmasıdır.
Normal GET her zaman gövde içeren tam yanıt döndürür. Conditional GET sürüm kontrol başlıkları (ETag, tarih) ekler. Veriler değişmemişse, sunucu gövdesiz 304 yanıtı verir, trafik ve yükleme süresinden tasarruf sağlar.
Etkili önbellekleme için, her sunucu yanıtından ETag ve Last-Modified'ı yerel bir veritabanına kaydedin. Sonraki istekte, bunları If-None-Match ve If-Modified-Since başlıklarında gönderin. 304'te, yerel önbellekteki verileri kullanın.
304 yanıtında, sunucu yanıt gövdesini iletmez — yalnızca başlıklar (~200 bayt). 50 KB'lık bir kaynak için bu, %99,6 trafik tasarrufu anlamına gelir. Günde 50 kez senkronize olan bir uygulama için tasarruf ayda onlarca megabayta ulaşır.
Evet, bu standart yaklaşımdır — delta senkronizasyonu için. İstemci, Conditional GET aracılığıyla her kaynağın güncelliğini kontrol eder, yalnızca değişenleri indirir ve yerel değişiklikleri gönderir. Bu yaklaşım Twitter, Instagram, Telegram ve çoğu modern API'de kullanılır.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.