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órzeniePOSTmoż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ć /rezerwacje → 401. 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.
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)