ETag у апликацијама — шта је то, намена и принцип

Аутор: IT Sectr Објављено: 2026-06-14 Време читања: 7 мин

ETag — HTTP заглавље одговора које садржи јединствени идентификатор верзије ресурса. Сервер генерише ETag као хеш садржаја или број верзије и враћа га клијенту заједно са подацима. При наредним захтевима, клијент шаље овај идентификатор у заглављу If-None-Match, омогућавајући серверу да провери да ли се ресурс променио. Према MDN Web Docs, 2025, ETag је основа механизма условних GET захтева у HTTP. Условни захтеви са ETag смањују обим пренетих података при синхронизацији мобилних апликација до 90%.

Главно

  • ETag — HTTP заглавље које садржи јединствени идентификатор верзије ресурса, обично хеш његовог садржаја.
  • If-None-Match — клијент шаље сачувани ETag, сервер враћа 304 Not Modified ако се ресурс није променио.
  • Уштеда саобраћаја — условни захтеви са ETag смањују обим података при синхронизацији мобилних апликација, јер се тело одговора не преноси.
  • Јаки и слаби ETag — јаки разликују садржај бајт по бајт, слаби дозвољавају семантичку еквивалентност ресурса.
  • Примена — ETag се користи у REST API за синхронизацију података, кеширање и спречавање конфликата при уређивању.

Шта је ETag у HTTP и мобилним апликацијама?

ETag (Entity Tag) — HTTP заглавље из породице условних заглавља које обезбеђује валидацију кешираних ресурса. Сервер израчунава ETag као хеш суму (MD5, SHA-256) или број верзије ресурса и враћа га у одговору на GET захтев. Клијент чува ETag заједно са подацима и при поновном захтеву шаље га у заглављу If-None-Match. Ако се садржај ресурса није променио, сервер одговара статусом 304 Not Modified без тела одговора.

За мобилне апликације, ETag је критичан јер смањује обим преузетих података. При сваком покретању или синхронизацији, апликација проверава актуелност ресурса захтевом са If-None-Match — уместо потпуног преузимања података, добија 304 и користи локалну копију. Према Google Chrome Team (2024), коришћење ETag у мобилним API смањује просечан обим одговора за 87% за листе и за 94% за појединачне објекте.

ETag се генерише на страни сервера и може бити како детерминистички (исти за исти садржај, што је корисно за дељене кеш меморије), тако и јединствен за сваки одговор (за строгу валидацију). У REST API намењеним за мобилну синхронизацију, најчешће се користи комбинација хеша садржаја и броја верзије записа у бази података.

Типови ETag: јаки и слаби идентификатори

Јаки ETag (strong ETag) — идентификатори који се мењају при свакој промени садржаја, укључујући и незнатне (размаци, форматирање). Формат: "abc123def" (у двоструким наводницима, без префикса). Јаки ETag гарантују да се ресурс није променио бајт по бајт. Они су обавезни за захтеве опсега (Range requests) и за проверу интегритета делимичних преузимања.

Слаби ETag (weak ETag) — идентификатори са префиксом W/, на пример W/"abc123def". Они дозвољавају да је ресурс семантички еквивалентан, чак и ако се бајтовна репрезентација разликује. Слаби ETag су корисни за сервере који динамички генеришу одговоре са различитим размацима или форматом, али истим значењем. Међутим, слаби ETag не подржавају захтеве опсега.

Поређење типова ETag:

КарактеристикаЈаки ETagСлаби ETag
Формат"hash"W/"hash"
ОсетљивостБајт по бајтСемантичка
Range захтевиПодржаниНису подржани
Кеширање CDNИдеалноОграничено
СинхронизацијаВисока прецизностДозвољава колизије

ETag против Last-Modified: шта одабрати

Last-Modified — HTTP заглавље које указује датум и време последње измене ресурса. Клијент га шаље назад у заглављу If-Modified-Since. Last-Modified је једноставнији за имплементацију (серверу је потребан само датум), али има фундаментална ограничења: резолуцију од једне секунде (две промене у једној секунди су неразмрсиве) и немогућност утврђивања да ли се садржај променио у истом тренутку (нпр. након враћања из резервне копије).

ETag решава ове проблеме: хеш садржаја се мења при свакој промени независно од времена. Због тога савремени REST API користе комбинацију оба заглавља: ETag за прецизну валидацију и Last-Modified за приближно филтрирање на CDN-у. Apache HTTP Server и Nginx подразумевано генеришу оба заглавља за статичке датотеке.

За мобилне апликације са синхронизацијом, ETag је критичнији јер омогућава откривање конфликата при уређивању. Ако клијент шаље PUT захтев са заглављем If-Match: "etag", сервер одбија захтев ако је ресурс измењен од стране другог клијента (оптимистичко закључавање). Last-Modified не може да гарантује такву поузданост због секундне прецизности.

Примери рада са ETag у Kotlin

Размотримо клијентску имплементацију ETag у мобилној апликацији на Kotlin коришћењем Retrofit и OkHttp. При сваком GET захтеву, клијент чува ETag из одговора, а при следећем захтеву шаље га у заглављу If-None-Match. Ако сервер врати 304, подаци се не преузимају поново.

Подешавање OkHttp клијента са кеширањем ETag:

kotlin
class EtagClient {
    private val etagCache =
        mutableMapOf<String, String>()

    private val client = OkHttpClient.Builder().build()

    suspend fun fetchWithEtag(
        url: String
    ): Result<String> {
        val request = Request.Builder()
            .url(url)
            .header("If-None-Match",
                etagCache[url] ?: "")
            .build()

        val response = client.newCall(request).await()

        return when (response.code) {
            304 -> Result.success(
                "not_modified")
            200 -> {
                response.header("ETag")?.let {
                    etagCache[url] = it
                }
                Result.success(response.body?.string()
                    ?: "")
            }
            else -> Result.failure(
                Exception("HTTP ${response.code}"))
        }
    }
}

Клијент чува ETag након успешног одговора 200 и шаље га у заглављу If-None-Match при следећем захтеву. При 304, клијент зна да је локална верзија актуелна и не троши саобраћај на поновно преузимање података. Овај образац смањује мрежне трошкове мобилне апликације за 80–90% за често тражене ресурсе.

Улога ETag у синхронизацији мобилних апликација

ETag је кључни механизам за оптимизацију синхронизације мобилних апликација са REST API. У стандардној шеми синхронизације, клијент прво захтева листу ресурса са ETag валидацијом — ако се ниједан ресурс није променио, сервер враћа 304 и клијент завршава синхронизацију. Ако постоје промене, сервер враћа само измењене ресурсе. Овај приступ се назива делта синхронизација и критичан је за мобилне уређаје са ограниченим саобраћајем.

У сценаријима са оптимистичким закључавањем, ETag се користи за спречавање Lost Update конфликата. Када клијент шаље PUT захтев за ажурирање ресурса, укључује заглавље If-Match: "etag". Ако се ETag не поклапа (други клијент је већ изменио ресурс), сервер одговара са 412 Precondition Failed, и клијент мора поново да преузме актуелну верзију и понови измену. Овај приступ обезбеђује конзистентност података без закључавања на нивоу базе података.

За дистрибуиране системе са офлајн режимом, ETag се користи у комбинацији са решавањем конфликата. Клијент се синхронизује добијајући актуелне ETag за све ресурсе. При слању измена, сервер проверава If-Match — ако се ETag не поклапа, региструје се конфликт који се решава по изабраној стратегији (LWW, Merge). Према Postman API Report (2025), 67% производних REST API за мобилне апликације користи ETag као главни механизам валидације верзија.

Често постављана питања

Шта је HTTP заглавље ETag?

ETag — HTTP заглавље одговора које садржи јединствени идентификатор верзије ресурса. Клијент га користи за условне захтеве: ако се ресурс није променио, сервер враћа 304 Not Modified без тела одговора, штедећи саобраћај.

Која је разлика између ETag и Last-Modified?

ETag користи хеш садржаја за прецизно поређење. Last-Modified се заснива на датуму измене са прецизношћу од секунде. ETag је поузданији за откривање стварних промена и подржава оптимистичко закључавање преко If-Match.

Шта су јаки и слаби ETag?

Јаки ETag (без префикса) разликују ресурсе бајт по бајт. Слаби ETag (са префиксом W/) дозвољавају семантичку еквивалентност. Јаки су потребни за захтеве опсега, слаби за динамички генерисан садржај.

Како ETag помаже у мобилној синхронизацији?

ETag смањује саобраћај за 80–90%: клијент проверава актуелност свих ресурса кроз If-None-Match, преузимајући само измењене. Без ETag, клијент би преузимао пуне податке при свакој синхронизацији, трошећи саобраћај и батерију.

Како имплементирати ETag на серверу?

Сервер израчунава ETag као хеш (MD5, SHA-256) садржаја одговора или користи број верзије записа из базе података. У Spring Boot, довољна је анотација @Cacheable са etag = true. У Express.js, middleware etag је подразумевано укључен.

Закључак

  • ETag — HTTP заглавље за валидацију верзија ресурса, засновано на хешу садржаја или броју верзије.
  • Условни захтеви — клијент шаље If-None-Match са сачуваним ETag, сервер одговара 304 при одсуству промена.
  • Типови ETag — јаки (бајт по бајт, за Range захтеве) и слаби (семантичка еквивалентност, префикс W/).
  • Предност — ETag је прецизнији од Last-Modified, јер се хеш мења при свакој промени садржаја независно од времена.
  • Оптимистичко закључавање — преко If-Match, ETag спречава Lost Update конфликте при конкурентном уређивању ресурса.
  • Делта синхронизација — на ETag се заснивају шеме синхронизације код којих се преносе само измењени ресурси.
  • Препорука — увек додајте ETag у REST API за мобилне апликације. Комбинујте са Last-Modified за компатибилност са CDN и прокси серверима.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође