Conditional GET: какво е, механизъм на условна заявка

Автор: IT Sectr Публикувано: 2026-06-14 Време за четене: 7 мин

Conditional GET (условна GET заявка) — HTTP механизъм, позволяващ на клиента да провери актуалността на кеширания ресурс преди пълно зареждане. Клиентът изпраща GET заявка със заглавки If-None-Match (съдържа ETag) или If-Modified-Since (съдържа дата) и сървърът връща 304 Not Modified без тяло на отговора, ако ресурсът не е променен. Според MDN Web Docs, 2025, условните заявки намаляват мрежовия трафик на сървъри и клиенти. 304 Not Modified — ключов HTTP статус за ефективна синхронизация на мобилни приложения.

Основни точки

  • Conditional GET — HTTP заявка със заглавки If-None-Match или If-Modified-Since за проверка на актуалността на кеша.
  • 304 Not Modified — отговор на сървъра, показващ, че ресурсът не е променен. Тялото на отговора не се предава, спестявайки трафик.
  • If-None-Match — заглавка с ETag (хеш на версия), осигуряваща точна проверка на ниво съдържание на ресурса.
  • If-Modified-Since — заглавка с дата на последна промяна, по-лесна за реализация, но по-малко точна (разделителна способност 1 секунда).
  • Ефективност — Conditional GET намалява обема на данните при синхронизация с 80–95% за непроменени ресурси.

Какво е Conditional GET в HTTP?

Conditional GET — е GET заявка, съдържаща една или повече условни заглавки, въз основа на които сървърът решава дали да върне пълен отговор или само статус 304 Not Modified. Основната цел е да се избегне предаването на тялото на отговора, ако ресурсът не се е променил от последната заявка. Това е основен механизъм на HTTP кеширане, дефиниран в спецификацията RFC 7232.

За мобилни приложения Conditional GET е един от най-ефективните начини за оптимизиране на мрежовия трафик. Типичен сценарий: при отваряне на приложението клиентът изпраща серия от условни GET заявки за зареждане на емисията, профила и настройките. Ако данните не са се променили, приложението получава 304 и използва локално копие. Това отнема милисекунди вместо секунди и не изразходва мобилен трафик.

Според Google Web Fundamentals (2025), внедряването на условни GET заявки в мобилно приложение намалява средното време за зареждане с 40–60% за повторни посещения и намалява консумацията на трафик със 70–90% за страници с редки актуализации. Ефектът е особено забележим при бавни връзки (3G, Edge), където всеки байт е от значение.

Как работи условната GET заявка

Процесът се състои от три стъпки. Първа — клиентът изпраща обикновена GET заявка, сървърът връща ресурса заедно със заглавки за кеширане (ETag, Last-Modified). Втора — клиентът запазва ресурса и неговите валидатори локално. Трета — при повторна заявка клиентът изпраща GET с If-None-Match (за ETag) и/или If-Modified-Since (за Last-Modified). Сървърът проверява валидаторите и отговаря с 304, ако ресурсът не е променен, или 200 с нови данни.

Сървърът използва приоритет на ETag пред Last-Modified, когато и двете заглавки са налични. Това е така, защото ETag осигурява по-точна валидация — хешът на съдържанието се променя при всяка промяна, докато Last-Modified има разделителна способност от една секунда. Ако ETag съвпада, сървърът незабавно връща 304, без да проверява Last-Modified.

Пример за пълен цикъл на Conditional GET в последователността на заявките:

kotlin
// Стъпка 1: Първа заявка — получаване на данни и ETag
GET /api/profile
Response: 200 OK
ETag: "33a64df551425fcc55e"
Body: { "name": "Alice" }

// Стъпка 2: Повторна заявка — с If-None-Match
GET /api/profile
If-None-Match: "33a64df551425fcc55e"
Response: 304 Not Modified
// Тялото на отговора липсва — използвайте локално копие

Във втората заявка сървърът сравнява ETag от If-None-Match с текущия хеш на ресурса. При съвпадение се връща 304 без тяло — клиентът продължава да използва кешираните данни. Това е същността на Conditional GET: минимален трафик при максимална актуалност на данните.

Conditional GET срещу обикновена GET

Обикновената GET заявка винаги връща пълен отговор 200 OK с тяло. Дори ако ресурсът не е променен, сървърът предава всички данни отново. Това е приемливо за малки ресурси или редки заявки, но за мобилни приложения със стотици заявки при всяко стартиране, такъв подход води до прекомерна консумация на трафик и батерия.

Conditional GET добавя допълнителен товар под формата на заглавки (обикновено 50–200 байта на заявка), но спестява килобайти и мегабайти при отговор 304. Колкото по-голям е ресурсът, толкова по-изгодна е условната заявка. За изображения, списъци с данни и JSON документи с размер от 10 KB нагоре, Conditional GET се изплаща още от първата повторна заявка.

Сравнение на двата подхода:

ПараметърОбикновена GETConditional GET
Трафик (без промени)Пълен отговорСамо заглавки (~200 байта)
ЗакъснениеПълно зарежданеМилисекунди (304)
Натоварване на сървъраГенериране + предаванеСамо проверка на ETag
Сложност на реализациятаМинималнаИзисква съхранение на ETag
Ефективност за големи данниНискаВисока

Примери за реализация в Kotlin

Нека разгледаме пълна реализация на Conditional GET в Kotlin с използване на OkHttp и Room за съхранение на ETag. Приложение за списък със задачи зарежда задачи от сървъра и използва условни заявки за минимизиране на трафика. ETag се съхраняват в локална база данни за запазване между сесиите.

Репозиториум с Conditional GET в Kotlin:

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() // от локален кеш
            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 проверява кода на отговора: 304 означава липса на промени и данните се връщат от локалния кеш на Room. При 200 новият ETag се запазва, а задачите се актуализират в локалната база данни. Този модел е стандарт за мобилни приложения, синхронизиращи се чрез REST API.

Приложение на Conditional GET в мобилната разработка

Conditional GET се използва широко в мобилни приложения за оптимизиране на синхронизацията на данни. Основни сценарии: зареждане на новинарска емисия (Twitter, Instagram периодично запитват API с If-None-Match), актуализиране на потребителски профил, зареждане на списък с известия и синхронизация на задачи. Във всеки случай приложението може да провери актуалността на данните, без да ги презарежда.

За офлайн-first приложения Conditional GET служи като първи етап на синхронизация. Приложението първо изпраща условни GET заявки за всички ресурси, които са били локално променени от последната синхронизация. Ресурсите с 304 не изискват зареждане. След това приложението изпраща PUT/POST за локални промени. Такъв двуфазен подход осигурява минимална консумация на трафик.

В комбинация с Conflict Resolution, Conditional GET позволява ефективно откриване на конфликти. Ако клиентът е получил 200 с нови данни (ресурсът е променен), но клиентът има неизпратени локални промени — се регистрира конфликт. Клиентът може да приложи LWW (локалните промени се губят) или да стартира Merge Strategy за обединяване на локални и отдалечени промени. Според Meta Engineering Blog (2025), внедряването на Conditional GET в Messenger намали средната консумация на трафик за синхронизация със 73%.

Често задавани въпроси

Какво е Conditional GET заявка?

Conditional GET — HTTP GET заявка с условни заглавки (If-None-Match, If-Modified-Since). Сървърът връща 304 Not Modified, ако ресурсът не е променен, или 200 с нови данни. Това е механизъм за ефективно кеширане.

Как Conditional GET се различава от обикновена заявка?

Обикновената GET винаги връща пълен отговор с тяло. Conditional GET добавя заглавки за проверка на версията (ETag, дата). Ако данните не са се променили, сървърът отговаря с 304 без тяло, спестявайки трафик и време за зареждане.

Как да използваме Conditional GET за кеширане?

За ефективно кеширане запазвайте ETag и Last-Modified от всеки отговор на сървъра в локална база данни. При следващата заявка ги изпращайте в заглавките If-None-Match и If-Modified-Since. При 304 използвайте данните от локалния кеш.

Как Conditional GET помага за спестяване на трафик?

При отговор 304 сървърът не предава тяло на отговора — само заглавки (~200 байта). За ресурс с размер 50 KB това означава спестяване на 99.6% от трафика. За приложение, което се синхронизира 50 пъти дневно, спестяването достига десетки мегабайта на месец.

Може ли Conditional GET да се използва за синхронизация?

Да, това е стандартният подход за делта синхронизация. Клиентът проверява актуалността на всеки ресурс чрез Conditional GET, зарежда само променените и изпраща локални промени. Този подход се използва в Twitter, Instagram, Telegram и повечето съвременни API.

Обобщение

  • Conditional GET — HTTP механизъм за проверка на актуалността на кеширани ресурси чрез условни заглавки If-None-Match и If-Modified-Since.
  • 304 Not Modified — отговор на сървъра, показващ, че ресурсът не е променен. Тялото на отговора не се предава, спестявайки трафик и време за зареждане.
  • ETag срещу Last-Modified — ETag е по-точен (хеш на съдържание), Last-Modified е по-прост (дата). Препоръчва се комбиниране на двата за максимална ефективност.
  • Спестяване на трафик — за непроменени ресурси Conditional GET намалява обема на предаваните данни със 70–95% в зависимост от размера на ресурса.
  • Приложение — стандартен механизъм за синхронизация в Twitter, Instagram, Telegram и повечето съвременни REST API.
  • Интеграция — от страна на клиента се изисква съхранение на ETag в локална база данни, от страна на сървъра — генериране и сравнение на ETag при всяка заявка.
  • Препоръка — реализирайте Conditional GET за всички GET крайни точки в мобилното API. Това е най-евтиният начин за оптимизация с най-голям ефект за потребителите.

Ще разработим мобилно приложение под ключ

IT Sectr създава iOS и Android приложения за стартъпи и бизнеси от 2017 г. Ще ви консултираме и ще предложим най-доброто решение.

Обсъдете проекта

Прочетете също