Spotkanie 1: Architektura i protokół HTTP

🌐 Część I — Architektura aplikacji sieciowych

🎯 Cele

Po tej części powinieneś rozumieć, z jakich warstw składa się typowa aplikacja sieciowa, czym różni się od zwykłego programu działającego lokalnie, jak wygląda komunikacja klient–serwer oraz jakie są główne style projektowania API. Poznasz też projekt, który będziemy budować przez cały semestr na laboratoriach.


1️⃣ Czym jest aplikacja sieciowa?

Aplikacja sieciowa (ang. network application) to program, którego części działają na różnych maszynach połączonych siecią i komunikują się ze sobą, wymieniając dane według ustalonego protokołu.

Kluczowa różnica względem programu lokalnego: stan i logika nie muszą żyć w tym samym procesie co interfejs użytkownika. Telefon żołnierza wysyłający zgłoszenie i serwer przechowujący dane o sprzęcie to dwa oddzielne programy, które nigdy nie współdzielą pamięci — jedyny sposób komunikacji to sieć.

🔹 Przykłady aplikacji sieciowych

  • System rezerwacji (hotel, poligon, sala wykładowa)
  • Bankowość internetowa
  • Komunikatory (WhatsApp, Signal)
  • Systemy ewidencji sprzętu i logistyki

2️⃣ Model klient–serwer

Najpopularniejszy model architektury aplikacji sieciowej.

Rola Zadanie
Klient Inicjuje żądanie, prezentuje wynik użytkownikowi (przeglądarka, aplikacja mobilna, inny serwer)
Serwer Nasłuchuje na żądania, przetwarza je, zwraca odpowiedź

Serwer nie “dzwoni” sam do klienta bez powodu — to klient zawsze inicjuje rozmowę. (Wyjątki: WebSocket, powiadomienia push — omówimy przy okazji wykładu o skalowalności.)

🔹 Dlaczego nie jeden wielki program?

Rozdzielenie klienta i serwera daje:

  • niezależne skalowanie — można dodać kolejne serwery bez zmiany klienta,
  • wielu klientów na jeden serwer — przeglądarka, aplikacja mobilna i inny system mogą korzystać z tego samego API,
  • aktualizacje bez przeinstalowywania — zmiana logiki na serwerze nie wymaga nic od użytkownika.

3️⃣ Warstwy aplikacji sieciowej

Typowa aplikacja sieciowa dzieli się na trzy warstwy:

Warstwa Odpowiada za Przykład technologii
Prezentacji (frontend) Interfejs użytkownika HTML/CSS/JS, aplikacja mobilna
Logiki biznesowej (backend) Reguły, walidację, przetwarzanie żądań Python (FastAPI), Java, Node.js
Danych Trwałe przechowywanie informacji PostgreSQL, SQLite, MongoDB

Schemat trójwarstwowy: Klient (frontend) ↔︎ API (backend) ↔︎ Baza danych

To inny podział niż poziomy ANSI/SPARC z kursów o bazach danych — ANSI/SPARC opisuje niezależność danych wewnątrz jednego DBMS (zewnętrzny/koncepcyjny/wewnętrzny widok tych samych danych), a warstwy tutaj to podział samej aplikacji na osobne procesy. Nie mylcie tych dwóch modeli — łączy je tylko to samo słowo “warstwa”.

Dlaczego backend nigdy nie powinien pozwalać frontendowi łączyć się z bazą wprost? Bo wtedy każdy klient musiałby znać hasło do bazy, strukturę tabel i reguły biznesowe — a zmiana schematu bazy złamałaby każdą aplikację kliencką osobno.


4️⃣ Protokoły komunikacyjne

Aby klient i serwer się zrozumiały, muszą mówić tym samym językiem — protokołem.

🔹 Miejsce HTTP w stosie sieciowym

Warstwa (uproszczony model) Przykład protokołu
Aplikacji HTTP/HTTPS, FTP, SMTP
Transportowa TCP, UDP
Sieciowa IP

HTTP (HyperText Transfer Protocol) w wersjach 1.1 i 2 działa na bazie TCP — zanim popłynie choćby bajt danych HTTP, klient i serwer muszą nawiązać połączenie TCP (tzw. three-way handshake). HTTPS to HTTP owinięte w warstwę szyfrowania TLS.

⚠️ HTTP/3 to wyjątek: rezygnuje z TCP na rzecz protokołu QUIC (zbudowanego na UDP, RFC 9114) — głównie po to, by uniknąć tzw. head-of-line blocking przy zgubionych pakietach. W tym kursie pracujemy na semantyce HTTP/1.1, więc “HTTP na TCP” jest tu poprawnym uproszczeniem — ale nie uogólniajcie tego na każdą wersję protokołu.

Szczegóły samego HTTP (metody, nagłówki, kody odpowiedzi) to temat części II tego spotkania — na razie tylko umiejscawiamy go w stosie.


5️⃣ Style projektowania API

Kiedy backend ma udostępnić swoje możliwości innym programom, robi to przez API (Application Programming Interface). Kilka konkurencyjnych stylów:

Styl Format danych Charakterystyka
REST zwykle JSON zasoby adresowane przez URL, operacje przez metody HTTP — dominujący styl dziś
SOAP XML sztywny kontrakt (WSDL), popularny w starszych systemach korporacyjnych/rządowych
GraphQL JSON klient sam opisuje, jakich danych potrzebuje, w jednym zapytaniu
gRPC binarny (Protocol Buffers) bardzo szybki, typowany, głównie do komunikacji między mikroserwisami
WebSocket dowolny dwukierunkowy, trwały kanał — do komunikacji w czasie rzeczywistym (czat, powiadomienia)

W tym kursie skupiamy się na REST — to on zdominował publiczne API i będzie tym, co zbudujesz na laboratoriach.

🔹 Zasada REST w jednym zdaniu

Każdy zasób (rzecz, którą aplikacja przechowuje) ma swój adres URL, a to, co chcemy z nim zrobić, wyrażamy metodą HTTP (GET = pobierz, POST = utwórz, PUT/PATCH = zmień, DELETE = usuń) — nie czasownikiem w samym adresie.

Przykład: zamiast GET /pobierzRezerwacje?id=5, w REST piszemy GET /rezerwacje/5. Adres opisuje co, metoda HTTP opisuje jak.


6️⃣ Projekt semestralny: system rezerwacji poligonu

Przez wszystkie spotkania laboratoryjne zbudujemy razem jeden, rosnący system: rezerwację poligonu/strzelnicy dla jednostki wojskowej.

🔹 Aktorzy systemu

Rola Może
Planista poligonu zarządzać dostępnością poligonów, zatwierdzać/odrzucać rezerwacje
Dowódca jednostki rezerwować poligon dla swojego pododdziału
(gość/niezalogowany) tylko przeglądać dostępność, bez rezerwacji

🔹 Główne zasoby (na razie koncepcyjnie — do API dojdziemy w części II dzisiejszego spotkania)

  • Poligon — nazwa, lokalizacja, dostępne przedziały czasowe, typ (strzelnica, teren manewrowy…)
  • Jednostka — nazwa, dowódca
  • Rezerwacja — który poligon, która jednostka, od kiedy do kiedy, status (oczekująca, zatwierdzona, odrzucona)

🔹 Kluczowy problem projektowy

Dwie jednostki nie mogą zarezerwować tego samego poligonu w nakładających się przedziałach czasu. To pozornie proste wymaganie wróci wielokrotnie — przy walidacji danych, przy autoryzacji (kto może zatwierdzić konflikt) i przy współbieżności (co gdy dwie rezerwacje przychodzą w tej samej sekundzie).

💡 Zapamiętaj ten problem — będziemy go rozwiązywać stopniowo, warstwa po warstwie, przez cały semestr.


🧾 Podsumowanie części I

  • Aplikacja sieciowa rozdziela klienta i serwer, komunikujących się przez sieć według ustalonego protokołu.
  • Typowy podział to trzy warstwy: prezentacji, logiki biznesowej, danych.
  • HTTP to protokół aplikacyjny działający na TCP; HTTPS dodaje szyfrowanie TLS.
  • REST to dominujący dziś styl API: zasoby jako adresy URL, operacje jako metody HTTP.
  • Semestralny projekt: system rezerwacji poligonu — zaczynamy od środowiska pracy i pierwszego serwera na dzisiejszym laboratorium.

📡 Część II — Protokół HTTP w szczegółach

🎯 Cele

Po tej części będziesz rozumieć strukturę żądania i odpowiedzi HTTP, znał najważniejsze metody i kody statusu, oraz wiedział, dlaczego HTTP jest protokołem “bezstanowym” i co to oznacza w praktyce dla projektowania aplikacji.


1️⃣ Anatomia żądania HTTP

Kiedy przeglądarka (albo curl, albo Wasz kod) wysyła żądanie, wygląda ono (uproszczone) tak:

GET /poligony/5 HTTP/1.1
Host: sebastianzajac.pl
Accept: application/json
Authorization: Bearer eyJhbGc...

(puste ciało — GET zwykle go nie ma)
Element Znaczenie
Linia startowa metoda + ścieżka + wersja protokołu
Nagłówki (headers) metadane: co akceptujemy, kim jesteśmy, jaki format wysyłamy
Ciało (body) właściwe dane (przy GET zwykle puste, przy POST/PUT — tak)

2️⃣ Metody HTTP — czasowniki REST-a

Metoda Znaczenie Ma ciało? Bezpieczna?* Idempotentna?**
GET pobierz zasób nie tak tak
POST utwórz nowy zasób tak nie nie
PUT zastąp cały zasób tak nie tak
PATCH zmodyfikuj część zasobu tak nie nie (zwykle)
DELETE usuń zasób nie nie tak

* Bezpieczna (safe) = nie zmienia stanu serwera — można ją wywołać wielokrotnie bez skutków ubocznych (przeglądarka może np. prefetchować linki GET). ** Idempotentna = wielokrotne wykonanie daje ten sam efekt co jednokrotne. DELETE /poligony/5 wywołane dwa razy nadal kończy się brakiem poligonu 5 — drugie wywołanie nic nowego nie psuje (może zwrócić 404, ale stan systemu jest identyczny). POST nie jest idempotentny: dwukrotne wysłanie tworzy dwa zasoby.

⚠️ To rozróżnienie ma praktyczne znaczenie: jeśli klient nie dostał odpowiedzi (timeout sieciowy) i nie wie, czy żądanie dotarło, bezpiecznie może powtórzyć PUT/DELETE, ale powtórzenie POST może utworzyć duplikat.

3️⃣ Kody statusu — pięć rodzin

Zakres Rodzina Przykłady
1xx Informacyjne rzadko używane bezpośrednio w API
2xx Sukces 200 OK, 201 Created, 204 No Content
3xx Przekierowanie 301 Moved Permanently, 304 Not Modified
4xx Błąd klienta 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found
5xx Błąd serwera 500 Internal Server Error, 503 Service Unavailable

🔹 Rozróżnienie, które myli początkujących: 401 vs 403

  • 401 Unauthorized — “nie wiem, kim jesteś” (brak albo niepoprawne uwierzytelnienie).
  • 403 Forbidden — “wiem, kim jesteś, ale nie masz uprawnień do tej operacji”.

Przykład z naszego projektu: żołnierz bez zalogowania próbujący zobaczyć /rezerwacje401. Zalogowany żołnierz próbujący zatwierdzić rezerwację (uprawnienie tylko planisty) → 403.

4️⃣ Nagłówki, które będziecie używać najczęściej

Nagłówek Rola
Content-Type jaki format ma ciało żądania/odpowiedzi (application/json)
Authorization dane uwierzytelniające (Bearer <token>) — wracamy do tego przy bezpieczeństwie
Accept jaki format klient chce dostać z powrotem
Cache-Control jak długo/czy wolno cache’ować odpowiedź

5️⃣ HTTP jest bezstanowy — co to znaczy naprawdę

Sam protokół HTTP nie niesie żadnego stanu między żądaniami — nie ma wbudowanego pojęcia “ta sama rozmowa co poprzednio”. To nie znaczy, że serwer nie wolno mu niczego pamiętać (serwer ma swoją bazę danych i może przechowywać, co chce) — znaczy to, że każde żądanie musi samo z siebie nieść informację potrzebną do jego obsłużenia (np. token w nagłówku), zamiast polegać na tym, że protokół “skojarzy” je z poprzednim żądaniem tego klienta.

💡 To dlaczego logowanie polega na tym, że klient za każdym razem wysyła token (w Authorization), a nie że serwer “pamięta”, że kogoś już zalogował 5 minut temu. Do mechanizmu tokenów wrócimy przy wykładzie o bezpieczeństwie.

NoteA cookies i sesje?

Historycznie serwery symulowały stan przez cookies + sesje po stronie serwera (Set-Cookie → przeglądarka odsyła ten sam identyfikator przy każdym żądaniu → serwer odnajduje zapisany stan w swojej pamięci/bazie). To dalej działa i bywa używane, ale w architekturach REST/API (szczególnie gdy klientem nie jest przeglądarka, tylko np. aplikacja mobilna) tokeny bezstanowe (JWT) są dziś częstszym wyborem — nie wymagają, żeby serwer pamiętał cokolwiek o sesji.

6️⃣ Cache — kiedy nie pytać serwera drugi raz

Cache-Control: max-age=3600 mówi klientowi (albo pośredniczącemu proxy): “ta odpowiedź jest ważna przez godzinę, nie pytaj mnie ponownie”. Dobrze zaprojektowane API rozróżnia zasoby, które warto cache’ować (lista dostępnych poligonów, zmienia się rzadko) od tych, których nie wolno (stan bieżącej rezerwacji — musi być zawsze aktualny).


🧾 Podsumowanie części II

  • Żądanie HTTP = linia startowa (metoda + ścieżka) + nagłówki + opcjonalne ciało.
  • Metody różnią się tym, czy są bezpieczne i idempotentne — to ma realne konsekwencje przy błędach sieciowych.
  • Kody 4xx to błąd po stronie klienta, 5xx — po stronie serwera; 401 ≠ 403.
  • HTTP jest bezstanowy — każde żądanie musi być samowystarczalne.

📚 Źródła

  • R. Fielding, Architectural Styles and the Design of Network-based Software Architectures
  • MDN Web Docs — An overview of HTTP, HTTP request methods, HTTP response status codes
  • RFC 9110 — HTTP Semantics
  • Dokumentacja FastAPI (framework używany na laboratoriach)