ETag (Entity Tag), sunucudaki bir kaynak sürümüne benzersiz bir tanımlayıcı atayan ve istemcinin önbelleğe alınmış verilerin güncelliğini verimli bir şekilde kontrol etmesini sağlayan bir HTTP başlığıdır. Tekrarlanan bir istekte, tarayıcı veya uygulama kaydedilmiş ETag'i gönderir ve sunucu bunu mevcut olanla karşılaştırır: eşleşirse, yanıt gövdesi olmadan 304 Not Modified durumunu döndürür. RFC 7232'ye (IETF, 2014) göre, ETag ile koşullu istekler, sık talep edilen kaynaklar için veri aktarım hacmini %95'e kadar azaltır. Bu, başlığı mobil uygulama performansı için kritik hale getirir.
Anahtar Noktalar
ETag (Entity Tag), bir kaynağın belirli bir sürümü için benzersiz bir tanımlayıcı içeren bir HTTP yanıt başlığıdır. Sunucu, ETag'i dosya içeriğine, meta verilerine veya revizyon numarasına göre hesaplar ve bir GET isteğine yanıt olarak istemciye gönderir. İstemci bu tanımlayıcıyı kaydeder ve aynı kaynağa yapılan sonraki isteklerde bunu If-None-Match başlığında gönderir. Kaynak değişmemişse, sunucu 304 Not Modified ile yanıt verir ve istemci önbelleğe alınmış kopyasını kullanır.
ETag biçimi RFC 7232'de tırnak içine alınmış bir dize olarak tanımlanmıştır: "33a64df551425fcc55e4d42a148795d9f25f89d4". Değer, dosya içeriğinin bir SHA-1 karması, artan bir sürüm numarası, statik dosyalar için inode-sayı-zaman birleşimi veya sunucu tarafından oluşturulan rastgele bir belirteç olabilir. Tek gereksinim, kaynak değiştiğinde değerin değişmesi ve kaynak aynı kaldığında değişmemesidir.
ETag, koşullu istek mekanizmalarına (conditional requests) aittir — HTTP protokolünün temel optimizasyonlarından biridir. Sunucunun her zaman tam bir yanıt döndürdüğü koşulsuz isteklerin aksine, koşullu bir istek, istemcinin verileri yeniden yüklemeden önbelleğin geçerliliğini kontrol etmesine olanak tanır. HTTP Archive (2025)'e göre, tüm HTTP yanıtlarının yaklaşık %40'ı, doğru ETag ve Last-Modified yapılandırması sayesinde 304 Not Modified'dır.
ETag, REST API'lerde veri koleksiyonlarının yüklenmesini optimize etmek için kullanılır — nesne listesi değişmemişse, istemci tüm JSON'u aktarmadan 304 alır. Statik dosyalar (CSS, JS, görseller) için ETag, CDN'lerin ve tarayıcıların önbellek tazeliğini verimli bir şekilde kontrol etmesine olanak tanır. Mobil uygulamalarda ETag, arka plan senkronizasyonu için kritiktir: uygulama, sunucudaki verilerin değişip değişmediğini kontrol eder ve güncellemeleri yalnızca gerektiğinde indirir. Bu, trafikten ve cihaz pilinden tasarruf sağlar.
Tam ETag yaşam döngüsü dört adımdan oluşur. Sunucu ilk istekte bir ETag oluşturur ve bunu yanıt başlığında döndürür. İstemci, ETag'i önbelleğe alınmış kaynakla birlikte kaydeder. Tekrarlanan bir istekte, istemci If-None-Match başlığını kaydedilmiş ETag değeriyle gönderir. Sunucu, alınan değeri mevcut kaynak ETag'i ile karşılaştırır: eşleşirse, boş gövdeyle 304 Not Modified döndürür; eşleşmezse, yeni kaynak ve yeni ETag ile 200 OK döndürür.
// If-None-Match ile istemci isteği
GET /api/users HTTP/1.1
Host: example.com
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
// Sunucu yanıtı — kaynak değişmedi
HTTP/1.1 304 Not Modified
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Bir mobil uygulamada bu döngü, önbellekleme desteği olan bir HTTP istemcisi aracılığıyla uygulanabilir. Örneğin OkHttp, CacheInterceptor aracılığıyla ETag'i otomatik olarak yönetir: yanıt ETag'ini kaydeder ve tekrarlanan isteklerde If-None-Match ekler. 304 aldığında OkHttp, önbelleğe alınmış verileri döndürür. OkHttp, ek yapılandırma olmadan ETag'i destekler — sadece OkHttpClient.Builder.cache() ile önbelleği etkinleştirin.
Sunucu ETag'leri farklı şekillerde hesaplayabilir: içeriğin MD5 veya SHA karmasıyla, veritabanından bir revizyon numarasıyla (örneğin MySQL'den updated_at), statik dosyalar için inode + mtime + boyut birleşimiyle (Nginx ETag'leri tam olarak bu şekilde oluşturur). Dinamik API'ler için içerik karması en güvenilir olanıdır: JSON yanıtında tek bir alan bile değişirse, ETag değişir. Ancak her istekte bir karma hesaplamak CPU'yu yükler — yüksek yüklü sistemler için artan bir sürüm numarası kullanmak daha iyidir.
RFC 7232 iki tür ETag tanımlar: güçlü (strong) ve zayıf (weak). Güçlü bir ETag, kaynağın iki temsilinin bayt bayt aynı olduğu anlamına gelir — tek bir bit bile farklı değildir. Zayıf bir ETag (önek W/) yalnızca anlamsal eşdeğerliği garanti eder: içerik serileştirme düzeyinde (boşluklar, JSON alan sırası) farklılık gösterebilir, ancak veriler istemci için aynı kabul edilir. Zayıf ETag'ler W/ önekiyle işaretlenir, örneğin W/"1a2b3c".
ETag türünün seçimi, karşılaştırma hassasiyeti gereksinimlerine bağlıdır. Statik dosyalar (CSS, JS, görseller) için güçlü ETag'ler tercih edilir — dosya değişmişse, istemci yeni sürümü almalıdır. Aynı JSON'un farklı alan sırası veya biçimlendirmeyle serileştirilebildiği dinamik API'ler için zayıf ETag'ler daha fazla esneklik sağlar: sunucu, dize temsili yerine iş verilerine dayalı olarak ETag oluşturur.
| ETag Türü | Biçim | Garanti | Kullanım |
|---|---|---|---|
| Strong (güçlü) | "karma" | Bayt bayt aynılık | Statik dosyalar, ikili kaynaklar |
| Weak (zayıf) | W/"karma" | Anlamsal eşdeğerlik | JSON API, dinamik sayfalar |
Zayıf ETag'lerin bir sınırlaması: aralık istekleri (Range requests) ile kullanılamazlar. İstemci bir dosyanın bir bölümünü talep ederse, sunucu parçanın tam kaynağa karşılık geldiğini garanti etmek için güçlü bir ETag döndürmelidir. Zayıf ETag'ler bu garantiyi sağlamaz. Diğer senaryolarda, zayıf ETag'ler güvenlidir ve API'ler için önerilir.
ETag ve Last-Modified, koşullu istekler için sıklıkla birlikte kullanılan iki HTTP başlığıdır. Last-Modified, bir kaynağın son değiştirilme tarihini belirtir ve If-Modified-Since başlığıyla çalışır. ETag, benzersiz bir sürüm tanımlayıcısı sağlar ve If-None-Match ile çalışır. Her birinin avantajları ve sınırlamaları vardır ve bunları birleştirmek maksimum önbellek verimliliği sağlar.
Last-Modified uygulaması daha basittir — sunucu tarihi otomatik olarak dosya sisteminden alır veya veritabanındaki updated_at alanını günceller. Ancak tarih, saniye düzeyinde hassasiyete sahiptir ve bu, saniyede birkaç kez değişen kaynaklar için yetersizdir. Ayrıca Last-Modified, farklı durumları ayırt etmez: bir dosya aynı sürümle üzerine yazılırsa, tarih değişir ancak içerik değişmez, bu nedenle istemci aynı verileri yeniden yükler.
ETag daha hassastır: yalnızca içerik gerçekten değiştiğinde değişir. Sunucu yedekten önceki bir sürümü geri yüklerse, ETag değişir. Bir dosya aynı verilerle üzerine yazılırsa, ETag aynı kalır ve istemci yeniden yükleme yapmaz. Birleşik kullanım, HTTP şartnamesi tarafından önerilir: sunucu her iki başlığı da döndürür, istemci If-None-Match ve If-Modified-Since'i aynı anda gönderir. En az bir başlık bir değişiklik gösteriyorsa, sunucu yeni bir kaynak döndürür.
Şartnameye göre ETag, Last-Modified'a göre önceliklidir. Sunucu If-None-Match alırsa, If-Modified-Since'i yok sayarak yalnızca ETag'i kontrol etmelidir. Bu, yarış durumunu önler: istemci Last-Modified'ı gönderdikten sonra ve sunucuda kontrol edilmeden önce kaynak değişirse, ETag daha güncel gösterge olacaktır. Pratikte sunucular genellikle her iki başlığı da kontrol eder, ancak sonuçlar uyuşmadığında ETag kazanır.
ETag yapılandırması sunucu türüne bağlıdır. Nginx, statik dosyalar için ETag'leri inode, mtime ve boyuta göre otomatik olarak oluşturur. Apache, FileETag mekanizmasını kullanır. Node.js, PHP, Python, Ruby üzerindeki dinamik uygulamalar için ETag'lerin programatik olarak oluşturulması gerekir — yanıt karması, veri sürüm numarası veya istek parametrelerinin birleşimi yoluyla.
func etagMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter,
r *http.Request) {
// Verilere dayalı ETag oluşturma
etag := generateETag(r.URL.Path)
w.Header().Set("ETag", etag)
// If-None-Match kontrolü
if r.Header.Get("If-None-Match") == etag {
w.WriteHeader(http.StatusNotModified)
return
}
next.ServeHTTP(w, r)
})
}
Go'daki Middleware, isteği keser, istenen URL için bir ETag oluşturur (örneğin, önbellekten veya DB'den bir veri karması hesaplar) ve yanıt başlığını ayarlar. İstemci If-None-Match göndermişse ve mevcut ETag ile eşleşiyorsa, sunucu ana işleyiciyi çağırmadan hemen 304 Not Modified döndürür. Üretimde, sunucu yükünü azaltmak için URL ve parametrelere göre hesaplanan ETag'lerin önbelleğe alınması eklenmelidir.
Bir çoklu sunucu yapılandırmasında (round-robin veya anycast), ETag aynı kaynak için tüm düğümlerde aynı olmalıdır. ETag dosya inode'una göre oluşturulursa ve site birden çok sunucuya dağıtılmışsa, değerler farklı olacaktır. Çözüm, içerik karması veya merkezi sürüm depolama (Redis, etcd) kullanmaktır. İkinci sorun gzip sıkıştırmasıdır: sıkıştırma etkinleştirildiğinde Nginx ETag'i değiştirir, bu da gereksiz 304 yanıtlarına neden olabilir. Sıkıştırılmış içerikle ETag'i senkronize etmek için gzip_vary on yapılandırılmalıdır.
Sıkça Sorulan Sorular
Evet, sunucu bunu açıkça engellemediyse. ETag'in küresel olarak benzersiz olması gerekmez — belirli bir URL içinde benzersizdir. Statik dosyalar için SHA karması kullanırken çakışmalar olası değildir, ancak özel oluşturucular yinelenenler üretebilir.
ETag, tekrar tekrar talep edilen ve nadiren değişen kaynaklar için en etkilidir: statik varlıklar, API listeleri, yapılandırmalar. Bir kez yüklenen benzersiz sayfalar için (örneğin bir sipariş onay sayfası), ETag avantaj sağlamaz.
CDN'ler, önbellek tazeliğini kontrol etmek için kaynak isteklerinde ETag'i dikkate alır. Kaynaktaki bir kaynağın ETag'i değişmişse, CDN yeni sürümü yükler. Cloudflare ve Fastly, ETag'i kaynak düzeyinde standart bir önbellek geçersiz kılma mekanizması olarak destekler.
RFC 7232 ETag uzunluğunu sınırlamaz, ancak sunucular ve proxy'ler aşırı uzun değerleri kısaltabilir veya yok sayabilir. 20–40 karakterlik bir karma veya sürüm tanımlayıcısı ve sağlama toplamı kombinasyonu kullanılması önerilir.
Bunlar birbirini dışlayan mekanizmalar değildir. Cache-Control önbellek politikasını (ne kadar süre saklanacağı, kimin izinli olduğu) tanımlarken, ETag önbelleğe alınmış kaynaklar için bir doğrulama mekanizmasıdır. En uygun yapılandırma her iki başlığı da içerir.
Ö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.
Ayrıca okuyun