vyvchy
    Теми розділу

    03 · Веб і мережі для AQA

    Клієнт-сервер і як працює веб

    Зміст

    Уяви прилавок у кавʼярні. Ти кажеш бариста, чого хочеш, і чекаєш. Бариста не подає тобі каву просто так, поки ти не попросив, і не знає наперед, хто зайде наступним. Ти теж не лізеш за стійку молоти : твоя справа — сформулювати замовлення, його справа — виконати. Веб побудований на цій самій асиметрії: одна сторона просить, інша обслуговує.

    Навіщо це тестувальнику. Коли тест «не бачить» кнопку, коли запит падає з кодом 500, коли той самий сценарій зелений локально й червоний на CI — за кожним випадком стоїть конкретна ланка обміну між клієнтом і сервером. Ця глава — карта: вона називає всі ланки й пояснює, за що кожна відповідає. Деталі розбирають окремі глави розділу, і на них тут стоять лінки; завдання цієї глави — дати систему координат, у якій ті деталі матимуть сенс.

    Клієнт і сервер: хто кого просить

    Клієнт (client) — програма, яка ініціює запит і споживає відповідь. Найзвичніший клієнт у вебі — браузер, але клієнтом може бути будь-що, що вміє надіслати мережевий запит: утиліта curl у терміналі, Postman, мобільний застосунок, автотест.

    Сервер (server) — програма, яка постійно слухає вхідні запити на певному порту й формує відповіді. Тут ховається перша плутанина: словом «сервер» називають і машину в дата-центрі, і програму-процес на ній. Далі в главі сервер — саме програма.

    Головне в цій моделі — не визначення, а асиметрія ролей. Клієнт знає, до кого звертатись; сервер зазвичай не знає наперед, хто до нього прийде. У класичній схемі «один запит — одна відповідь» сервер не заговорює першим: він лише відповідає на те, що прийшло.

    Чому взагалі так поділили? За поділом стоїть інженерний принцип розділення відповідальностей (separation of concerns): інтерфейс окремо від зберігання даних. Виграш подвійний — інтерфейс стає простіше переносити між платформами, а серверну частину простіше масштабувати, бо вона позбавлена турбот про відображення.

    Рівні: коли клієнта й сервера вже недостатньо

    Той самий поділ масштабують далі — на рівні (tiers). Рівнева архітектура (n-tier architecture) ділить застосунок на логічні шари (layers) і фізичні рівні (tiers): шар — це відповідальність (показати, порахувати, зберегти), рівень — машина, на якій та відповідальність виконується. Шари ходять в один бік: вищий користується послугами нижчого, а нижчий до вищого не звертається. Один шар — не обовʼязково один рівень: кілька шарів цілком можуть жити на одному.

    Звідси три знайомі конфігурації. Дворівнева — клієнт плюс сервер із даними: у варіанті, який описує гайд Microsoft, увесь код застосунку лежить на клієнті, а окремий сервер тримає базу. Трирівнева — клієнт звертається до застосунку, розгорнутого на окремому сервері, а той уже до бази на ще одному; для веб-застосунків і веб-сервісів це дуже поширена схема. Багаторівнева — коли рівнів більше за три: складніший застосунок розносить різні ділянки функціональності по кількох середніх рівнях. Плата за рознесення — мережа поміж рівнями: фізичний поділ додає масштабованості й стійкості, але й .

    Тестувальнику ця картина відповідає на питання «де шукати». Запити й дані, що проходять крізь кілька рівнів, ускладнюють тестування й моніторинг — червона перевірка на екрані показує симптом, а зламатися могло на будь-якому рівні за нею. Найчастіший приклад — перевірки введених даних: клієнтська валідація за MDN не є вичерпним заходом безпеки, її занадто просто обійти, а даним від клієнта довіряти не можна. Практичний висновок подвійний: баг «сервер прийняв те, чого форма не пускала» шукають не в UI, а рівнем нижче; і навпаки — правило, яке справді живе на сервері, перевіряється без UI взагалі, одним запитом до API.

    Наша практика (не канон). Клієнта, який тримає логіку в себе, команди звуть товстим (thick, або fat), а того, що лише показує готовий результат, — тонким (thin): це робочі слова з практики, окремого стандарту чи специфікації під них немає. Сам поділ під цими назвами не домашній — він про те, на якому рівні лежить код застосунку.

    Дворівнева:
    товстий клієнт
    логіка тут

    Сервер із даними

    Трирівнева:
    тонкий клієнт
    лише показує

    Сервер застосунку
    логіка тут

    База даних

    Багаторівнева:
    тонкий клієнт

    Кілька серверів
    логіка тут, у кожного
    своє навантаження

    База даних

    Дворівнева:
    товстий клієнт
    логіка тут

    Сервер із даними

    Трирівнева:
    тонкий клієнт
    лише показує

    Сервер застосунку
    логіка тут

    База даних

    Багаторівнева:
    тонкий клієнт

    Кілька серверів
    логіка тут, у кожного
    своє навантаження

    База даних

    Ключова думка діаграми: моделі різняться не кількістю прямокутників, а тим, по якому боку проходить межа відповідальності — товстий клієнт рахує й перевіряє сам, а тонкий лише показує те, що порахував сервер.

    Автотест — це теж клієнт

    Це найважливіший висновок глави для AQA. Твій тест не стоїть «збоку» від системи: у моделі він стоїть рівно там, де браузер чи curl, і має ті самі залежності від адрес, зʼєднань, статусів і оточення. Усе, що ламає браузер, ламає й тест.

    // обидва рядки — це запити клієнта, просто різними шляхами
    await page.goto('https://shop.example.com/cart');          // клієнт — браузер
    const res = await request.get('https://api.example.com/cart/42'); // клієнт — сам тест

    Різниця між рядками практична. Запит до API не залежить від верстки, анімацій і , тому ним зручно готувати : один POST замість десяти екранів клацання. А потім уже перевіряти інтерфейс на готовому стані.

    Один запит — одна фінальна відповідь

    Обмін має сталу форму. Запит складається з методу, шляху, заголовків і тіла (тіло є не завжди). Відповідь — зі , заголовків і тіла. Заголовки — це поля, які передаються перед тілом повідомлення.

    GET /cart?id=42 HTTP/1.1
    Host: shop.example.com
    Accept: text/html
    HTTP/1.1 200 OK
    Content-Type: text/html; charset=utf-8
    Content-Length: 5120

    Статус-код — тризначне число від 100 до 599; клас відповіді задає перша цифра. Формула «один запит — одна відповідь» точна лише щодо фінальної відповіді: перед нею може прийти нуль або більше проміжних із кодами класу 1xx (наприклад, 100 Continue чи 103 Early Hints), а вже за ними — рівно одна фінальна. Це не , а передбачений протоколом порядок.

    Методи, заголовки й тіло докладно розбирає глава «HTTP: методи, структура, заголовки», значення кодів — «HTTP статус-коди», а повний ланцюг від натискання Enter до сторінки на екрані — «Життєвий цикл запиту».

    Від імені до адреси: роль DNS

    Людина набирає shop.example.com, а мережа маршрутизує за числами. Перекладає одне в інше DNS (Domain Name System) — розподілена ієрархічна система, що складається з простору доменних імен, серверів імен і резолверів.

    Резолвер (resolver) — програма-прошарок між застосунком і серверами імен: приймає запит програми й за потреби йде ланцюжком далі — до кореневих серверів, потім до серверів зони .com, потім до авторитетних серверів самого домену, які й повертають адресу.

    Для тестів важлива не так механіка, як кеш. Кожен запис має TTL — час, скільки його дозволено тримати в кеші, перш ніж відкинути. Тому після переїзду стенда на нову адресу тести якийсь час стукають за старою: чекати доводиться саме TTL, а орієнтир джерела для типового вузла — порядок днів. Детально DNS розбирає глава «DNS, IP, порти та мережа».

    Адреса, порт і чому localhost іноді підводить

    IP-адреса (IP address) — числовий ідентифікатор вузла: за нею пакети знаходять дорогу до потрібної машини. Але машина одна, а програм на ній десятки, тому потрібен ще порт (port) — 16-бітне число від 0 до 65535, яке вказує, до якого саме сервісу йде зʼєднання. Пара «адреса + порт» називається сокетом, і саме пара сокетів (свій на кожному боці) однозначно визначає зʼєднання.

    Для стандартних схем порт можна не писати — мається на увазі типовий: 80 для http, 443 для https. Нестандартний вказують явно, як :3000 у локальному стенді.

    Окремий випадок — loopback: адреси 127.0.0.1 (IPv4) і ::1 (IPv6) означають «ця сама машина», і трафік на них нікуди не виходить у мережу. Звідси класична пастка: імʼя localhost веде на обидві ці адреси, тож якщо застосунок слухає лише 127.0.0.1, а клієнт пішов на ::1, зʼєднання «незрозуміло чому» не встановлюється. Рятує явна адреса замість імені.

    Рукостискання: про що домовляються до обміну

    Перш ніж піде корисний трафік, сторони узгоджують параметри — це (handshake). На шляху звичайного HTTPS-запиту їх щонайменше два.

    Перше — транспортне, тристороннє рукостискання TCP: SYNSYN-ACKACK. Кроків саме три, бо підтвердження й власний SYN сервера обʼєднані в одне повідомлення.

    Друге — криптографічне, TLS. Воно автентифікує сторони, узгоджує параметри шифрування й встановлює спільні ключі; починається з ClientHello, на який сервер відповідає ServerHello. HTTPS і є звичайний HTTP, загорнутий у цей шар: спершу піднімається захищений канал, а вже всередині нього ходить знайомий трафік. Гарантій рівно три: автентифікація (сервер автентифікується завжди, клієнт — опційно), конфіденційність і .

    Практичний наслідок: рукостискання платиться один раз на зʼєднання. Перший запит до нового хоста завжди дорожчий за наступні, бо keep-alive перевикористовує вже відкритий канал. Сертифікати, версії TLS і те, що ламається на цій фазі найчастіше, розбирає глава «HTTPS, TLS і безпека».

    Затримка і пропускна здатність — це різні речі

    Затримка (latency) — час, за який дані долають шлях від джерела до призначення; мережеву затримку зазвичай міряють туди й назад, як round-trip. (bandwidth) — міра того, скільки інформації може пройти крізь зʼєднання за заданий проміжок часу; міряють її кратними бітам за секунду (Mbps, Gbps).

    Величини незалежні, і плутати їх дорого. Канал буває водночас «товстим» і «довгим»: у TCP існує добуток «пропускна здатність × затримка», і мережі з великим його значенням мають власні проблеми продуктивності — їх так і називають, long fat network.

    Звідси різна діагностика. Сценарій із десятками дрібних API-викликів страждає від затримки — кожен виклик додає свій round-trip, і лікується це меншою кількістю походів у мережу. Сценарій із завантаженням великого файлу впирається в пропускну здатність, і лікується розміром корисного навантаження. Перший запит до хоста платить окремо: у його затримку входять DNS-пошук, рукостискання TCP і узгодження TLS.

    Саме тому оптимізації вебу здебільшого борються з кількістю round-trips: зʼєднань, мультиплексування в HTTP/2, , CDN; HTTP/3 поверх QUIC додатково поєднує встановлення транспортного зʼєднання з узгодженням TLS.

    Посередники на шляху: проксі, шлюз, тунель і CDN

    Малюнок «клієнт → сервер» правдивий лише в підручнику. Насправді запит іде ланцюгом зʼєднань, і на ньому стоять (intermediary). Форм три, і розрізняють їх не за місцем, а за роллю:

    • (proxy) — агент пересилання, якого обирає клієнт; типово його ставлять, щоб звести запити організації через спільного посередника заради безпеки або спільного кешу.
    • (gateway), він же reverse proxy, — посередник, який поводиться як origin-сервер для зовнішнього зʼєднання, а всередину пересилає запити іншим машинам. Балансувальник навантаження — окремий випадок шлюзу: розділення навантаження між кількома машинами названо серед його типових застосувань.
    • (tunnel) — сліпий ретранслятор, який повідомлень не змінює й учасником обміну не вважається.

    Клієнт
    браузер, curl, автотест

    Посередник
    проксі, шлюз, CDN

    origin-сервер

    База даних

    Клієнт
    браузер, curl, автотест

    Посередник
    проксі, шлюз, CDN

    origin-сервер

    База даних

    CDN (Content Delivery Network) — мережа проміжних серверів географічно ближче до користувачів: вона кешує відповіді, тож частина запитів до origin-сервера просто не доходить. З погляду HTTP це спільний кеш — той, що обслуговує кількох користувачів, на відміну від приватного кешу браузера.

    Два практичні наслідки. Коди 502 і 504 за означенням віддає сервер, який діє «as a gateway or proxy», — зламалася ланка за посередником, тоді як 503 означає, що сам сервер тимчасово не може обробити запит. І вузол, якого клієнт не обирав (корпоративний фаєрвол, публічний Wi-Fi), протокольно не відрізнити від на шляху — тож поведінка запиту здатна змінитися без жодної зміни в застосунку. Механіку кешу й посередників розбирає глава «Кешування».

    Безстановість: чому сервер тебе не памʼятає

    HTTP — безстановий (stateless) протокол: сервер за замовчуванням не памʼятає нічого про попередні запити, і кожен запит для нього чистий аркуш. Специфікація формулює це точніше: семантику кожного запиту можна зрозуміти ізольовано, а звʼязок між зʼєднанням і повідомленнями на ньому не впливає на їх інтерпретацію. Простіше кажучи, «ми ж щойно спілкувалися тим самим зʼєднанням» для сервера не аргумент.

    Навіщо так зробили: заради масштабованості й простоти. Якщо сервер не мусить памʼятати клієнтів, будь-який із десятка однакових серверів може обробити будь-який запит.

    Ключове уточнення, на якому валяться найчастіше: безстановий тут протокол, а не застосунок. Застосунок майже завжди має стан — твій кошик, твій профіль, — просто цей стан живе в базі даних і в тому, що клієнт приносить із кожним запитом.

    Звідси три наслідки для тестів. Кожен запит має нести все потрібне сам: токен чи кукі прикладаються до кожного звернення, а не «один раз при логіні». — той, у якого кілька однакових запитів дають той самий ефект, що й один; такими є PUT, DELETE і всі , тому наївний POST-запиту здатен створити дубль. І третій: оскільки протокол не тримає стану між запитами, ізольовані тести робляться легко — але й навпаки, будь-який спільний стан (дані в базі, кукі, глобальні ) створюєш ти сам, і саме він потім тече між тестами.

    Сесія: як застосунок памʼятає логін

    Якщо протокол не памʼятає нічого, як сайт памʼятає, що ти залогінений? Відповідь: клієнт сам нагадує про себе в кожному запиті. Класична схема така — сервер тримає запис сесії у себе (памʼять, Redis, база даних), а браузеру віддає лише ключ, ідентифікатор сесії.

    СерверБраузерСерверБраузербраузер зберігає кукіPOST /login (логін і пароль)200 OK, Set-Cookie: session_id=…GET /account, Cookie: session_id=…200 OK — сервер знайшов свій записСерверБраузерСерверБраузербраузер зберігає кукіPOST /login (логін і пароль)200 OK, Set-Cookie: session_id=…GET /account, Cookie: session_id=…200 OK — сервер знайшов свій запис

    Заголовки Set-Cookie і Cookie для того й існують: сервер зберігає стан на боці браузера, а браузер за збереженими метаданими сам вирішує, чи додати кукі до наступного запиту. Код сторінки цього не робить — і саме тому кукі-сесія переживає перезавантаження без жодних зусиль.

    Альтернатива — токен (token): стан зашитий у сам токен, і сервер запису не тримає. Токен кладуть або в кукі, або у сховище браузера — і в другому випадку він летить не автоматично, а вручну в заголовку Authorization. Ця різниця практична: токен зі сховища доїде до сервера рівно тоді, коли клієнтський код сам його туди поклав.

    Для тестів звідси випливає найкорисніша звичка розділу: не проклацувати форму логіну щоразу, а один раз отримати сесію й перевикористовувати . Кукі, їхні атрибути й сховище браузера — глава «Кукі, сесії та сховище браузера».

    SPA і MPA: де живе логіка складання сторінки

    Одна й та сама модель «запит — відповідь» дає дві різні архітектури, і від того, яку обрали в проєкті, залежить, як писати очікування.

    SPA (single-page application) завантажує лише один документ, а далі змінює вміст його тіла через JavaScript-API на кшталт fetch(). Переходи «між сторінками» документ не перезавантажують: адресу міняє History API — виклики history.pushState() і history.replaceState() змінюють URL без запиту на сервер. Протилежний полюс — MPA (multi-page application), де кожен екран є окремим документом: перехід означає, що браузер іде на сервер по новий документ і будує сторінку з нуля.

    Для тесту різниця в одному: чи існує момент «сторінка завантажилась». У MPA дочекатися завершення навігації відносно просто — є чіткі навігаційні події. У SPA старі сигнали завантаження не спрацьовують, і чекати доводиться на появу самого контенту. Стратегії рендерингу докладно розбирає глава «Асинхронне завантаження: SPA/MPA, CSR/SSR», а робота з DOM — «DOM, селектори та події».

    Наша практика (не канон). Термін MPA і означення «кожен екран — окремий документ» канонічного джерела не мають: так цей полюс називають команди, з якими ми працювали, і так його називатимуть на співбесіді. Сам механізм — повна навігація за новим документом — випливає з моделі «запит — відповідь», описаної вище.

    WebSocket: коли модель «запит — відповідь» не підходить

    Є клас функцій, де сервер мусить заговорити першим: чат, нотифікації, живі оновлення. У базовому HTTP такого способу немає, і до появи WebSocket двобічний обмін імітували опитуванням сервера — (polling); специфікація прямо називає це зловживанням HTTP.

    WebSocket — протокол двобічного обміну поверх одного TCP-зʼєднання. Відкривається він звичайним HTTP-запитом GET із заголовками Upgrade: websocket і Connection: Upgrade, а успіх підтверджує рівно один статус — 101 Switching Protocols. Далі це вже самостійний протокол, повʼязаний із HTTP лише способом відкриття: заголовки й повторна автентифікація на кожне повідомлення більше не потрібні. Схеми адрес — ws і wss (другий поверх TLS).

    Поруч живе простіший інструмент — Server-Sent Events (SSE): однобічний канал сервер → клієнт через інтерфейс EventSource і відповідь типу text/event-stream, із вбудованим автоперепідключенням.

    Для тестів головне те, що тут немає кореляції «запит — відповідь»: чекати треба на подію-наслідок — появу елемента, конкретний кадр, — а не на фіксований час. Реалтайм розбирає глава «WebSockets і реалтайм».

    REST: архітектурний стиль, а не протокол

    REST (Representational State Transfer) — не протокол і не стандарт, а архітектурний стиль: набір обмежень на взаємодію компонентів, описаний Роєм Філдінгом. Три з них ти вже прочитав у цій главі під іншими іменами: client-server (розділення відповідальностей), stateless (запит містить усе потрібне) і layered system (компонент не бачить далі сусіднього шару — саме тому на шляху можуть стояти посередники). Є ще кешованість, необовʼязковий code on demand і головне — єдиний інтерфейс (uniform interface): ідентифікація ресурсів, маніпуляція через представлення, самоописові повідомлення й гіпермедіа як рушій стану.

    Практично це дає простий поділ: що — задає адреса ресурсу, що з ним робимо — задає метод. GET запитує представлення ресурсу, POST просить сервер обробити передані дані, PUT створює або повністю замінює його стан, DELETE просить розірвати звʼязок ресурсу з його функціональністю. Формати даних і перевірки контракту — глава «REST API та формати даних».

    Версії HTTP: що змінюється, а що ні

    Версій протоколу кілька, і новачка це лякає дарма. Семантика — метод, шлях, заголовки, статус — від версії не залежить: специфікація навмисно задає вимоги так, щоб повідомлення однієї версії можна було ретранслювати іншими без зміни його змісту. Тому в панелі мережі ти бачиш ті самі поля незалежно від того, яка версія на дроті.

    Змінюється кодування. HTTP/1.1 текстовий — його можна прочитати очима, як у прикладі вище. У HTTP/2 ті самі повідомлення вкладені у двійкову структуру — кадр (frame); MDN називає три відмінності від HTTP/1.1: двійковість, мультиплексування (паралельні запити в одному зʼєднанні) і стиснення заголовків. HTTP/3 працює поверх QUIC і використовує на кожному потоці двійкове кадрування, подібне до кадрування HTTP/2.

    Наскільки це вже реальність: за даними, на які посилається MDN, вживання HTTP/2 досягло піку в січні 2022 — 46,9 % усіх сайтів; HTTP/3 у жовтні 2022 користувалися 26 % сайтів. Цифру подавай саме так — з датою й атрибуцією. Важливіше інше: перехід на нову версію не потребує змін у коді застосунку, тому в команді про нього можуть просто не сказати — інфраструктура оновилася, а тести побачили іншу поведінку мережі. Еволюцію протоколу розбирає глава «HTTP/2 і HTTP/3: еволюція протоколу».

    Типові помилки

    • Виглядає як «HTTP без стану, отже застосунок без стану», а насправді безстановий тут протокол: стан застосунку живе в базі даних і в тому, що клієнт приносить із кожним запитом.
    • Виглядає як «сервер памʼятає, що я залогінений», а насправді памʼятає застосунок за ключем, який браузер сам додає до кожного запиту; без ключа сервер бачить тебе вперше.
    • Виглядає як «сервер повільний», а насправді сценарій із десятків дрібних викликів упирається в затримку каналу, і ширша смуга його не прискорить.
    • Виглядає як «502 — це баг застосунку», а насправді код віддає посередник у ролі шлюзу чи проксі: зламалася ланка за ним, тоді як 503 каже про сам сервер.
    • Виглядає як «localhost і 127.0.0.1 — те саме», а насправді імʼя веде на обидві loopback-адреси, і застосунок, що слухає лише IPv4, для клієнта на ::1 недосяжний.
    • Виглядає як «сторінка завантажилась, дані мають бути», а насправді у SPA документ прийшов один раз, а вміст приносять фонові запити — чекати треба контент, а не навігацію.

    Підсумок

    1. Клієнт ініціює обмін, сервер відповідає; за поділом стоїть розділення відповідальностей — інтерфейс окремо від зберігання даних.
    2. Автотест у цій моделі — такий самий клієнт, як браузер чи curl, із тими самими залежностями від адрес, зʼєднань, статусів і оточення.
    3. На запит приходить рівно одна фінальна відповідь, якій можуть передувати проміжні 1xx; семантика повідомлення не залежить від версії протоколу.
    4. HTTP безстановий: кожен запит зрозумілий ізольовано й мусить нести все потрібне сам, а стан застосунку тримає база даних плюс те, що приносить клієнт.
    5. Між клієнтом і сервером стоять ланки, яких у коді не видно, — DNS, порти, рукостискання, посередники й CDN; більшість «незрозумілих» падінь живе саме там.

    Можливі питання

    • «Що відбувається після того, як я натиснув Enter в адресному рядку?» Слухають не завчений список, а розуміння порядку: імʼя в адресу, зʼєднання й рукостискання, запит, відповідь, побудова сторінки — і що на кожній ланці може зламатися.
    • «Що означає, що HTTP stateless?» Перевіряють головне уточнення: безстановий протокол, а не застосунок; стан живе в базі й у тому, що клієнт приносить із кожним запитом.
    • «Як сайт памʼятає, що я залогінений?» Дивляться на механізм, а не назву: сервер віддає ключ, браузер сам повертає його наступними запитами, сервер за ключем знаходить свій запис.
    • «Чим затримка відрізняється від пропускної здатності?» Питання на точність. Очікують дві різні величини й приклад, де вони дають різний діагноз: багато дрібних запитів проти одного великого файлу.
    • «Чим проксі відрізняється від reverse proxy?» Перевіряють, чи не переказуєш «стоїть зліва / стоїть справа»: проксі обирає клієнт, шлюз назовні поводиться як origin-сервер, а балансувальник — окремий випадок шлюзу.
    • «Коли WebSocket, а коли звичайний запит?» Очікують межу: якщо першим має заговорити сервер, модель «запит — відповідь» не підходить, і зʼєднання відкривається апгрейдом зі статусом 101.

    Джерела

    Клієнт і сервер: хто кого просить

    Рівні: коли клієнта й сервера вже недостатньо

    • Microsoft Learn — N-tier architecture style — шари vs рівні, односпрямованість викликів, кілька шарів на одному рівні, трирівневий склад, ціна фізичного поділу (масштабованість/стійкість проти затримок), ускладнення тестування й моніторингу.
    • Microsoft Application Architecture Guide, 2nd ed., ch.19 — склад дво- і трирівневої конфігурацій; трирівнева як дуже поширена для веб-застосунків і веб-сервісів.
    • MDN — Client-side form validation — клієнтська/серверна валідація, «не вичерпний захід безпеки», заборона довіри даним від клієнта.

    Автотест — це теж клієнт

    • RFC 9110 — HTTP Semantics — клієнт як програма, що встановлює зʼєднання й надсилає запити; автотест підпадає під те саме означення.
    • Playwright — API testing — запит до API поза UI і підготовка стану одним запитом.

    Один запит — одна фінальна відповідь

    • MDN — HTTP messages — склад запиту (метод, шлях, заголовки, тіло) і відповіді (статус, заголовки, тіло).
    • RFC 9110 — HTTP Semantics — заголовки як поля перед тілом, діапазон і клас статус-кодів, проміжні 1xx перед рівно однією фінальною відповіддю.

    Від імені до адреси: роль DNS

    Адреса, порт і чому localhost іноді підводить

    Рукостискання: про що домовляються до обміну

    Затримка і пропускна здатність — це різні речі

    Посередники на шляху: проксі, шлюз, тунель і CDN

    • RFC 9110 — HTTP Semantics — три форми посередника та їхні визначальні ознаки, балансування навантаження як застосування шлюзу, різниця 502/504 і 503, перехоплювальний вузол як нерозрізнимий від атаки на шляху.
    • MDN Glossary — CDN — CDN як мережа проміжних серверів ближче до користувача, що розвантажує origin.
    • RFC 9111 — HTTP Caching — поділ кешів на спільні й приватні.

    Безстановість: чому сервер тебе не памʼятає

    Сесія: як застосунок памʼятає логін

    • RFC 6265 — HTTP State Management MechanismSet-Cookie і Cookie як механізм стану поверх HTTP; агент користувача сам вирішує, чи повернути кукі.
    • MDN — Using HTTP cookies — сесійна кукі як ключ до запису сесії на сервері.
    • MDN — Authorization header — токен, який надсилають заголовком, а не автоматично.
    • Playwright — Authentication — одноразовий логін і збережений стан автентифікації замість форми в кожному тесті.

    SPA і MPA: де живе логіка складання сторінки

    • MDN Glossary — SPA (Single-page application) — SPA як застосунок, що завантажує один документ і оновлює його вміст через JavaScript.
    • MDN — History APIpushState() і replaceState() міняють URL без запиту на сервер.
    • Playwright — class Page — очікування навігації проти очікування появи контенту.
    • MDN — Window: load event — подія завантаження документа як сигнал, на який спираються навігаційні очікування.

    WebSocket: коли модель «запит — відповідь» не підходить

    REST: архітектурний стиль, а не протокол

    Версії HTTP: що змінюється, а що ні

    • RFC 9110 — HTTP Semantics — вимоги, незалежні від версії протоколу: повідомлення ретранслюється іншою версією без зміни змісту.
    • MDN — An overview of HTTP — двійкове кадрування повідомлень у HTTP/2.
    • RFC 9114 — HTTP/3 — двійкове кадрування на потоці, подібне до HTTP/2, поверх QUIC.
    • MDN — Evolution of HTTP — три відмінності HTTP/2, частки поширення з датами й нульова ціна переходу для застосунку.

    Пояснення

    «Поясни» працює з власним API-ключем Anthropic: запит іде з вашого браузера прямо до Anthropic.

    Свій API-ключ (BYOK)

    Вставте власний ключ Anthropic — пояснення працюватиме на реальній моделі. Ключ зберігається лише у вашому браузері (localStorage), нікуди не надсилається, крім api.anthropic.com, і не логується.