Protokół HTTP
HTTP (Hypertext Transfer Protocol) to najważniejszy protokół, na którym opiera się współczesny internet. Stworzony na początku lat 90. przez Tima Berners-Lee, stanowi fundament działania sieci WWW. Dzięki HTTP możliwa stała się wymiana informacji pomiędzy serwerami a przeglądarkami internetowymi, co całkowicie zmieniło sposób, w jaki korzystamy z technologii.
Protokół HTTP umożliwia przesyłanie stron internetowych, plików czy danych, wspierając niezliczoną liczbę aplikacji i usług online. w tej chwili codziennie obsługuje miliardy żądań – każde wejście na stronę, wysłanie formularza czy pobranie pliku odbywa się właśnie za jego pośrednictwem.
W tym artykule „Protokół HTTP dla początkujących” przyjrzymy się bliżej temu, jak działa ten protokół, jakie są jego możliwości oraz dlaczego jego znajomość jest tak ważna dla wszystkich programisty. Zrozumienie HTTP to pierwszy krok do skutecznego tworzenia i optymalizacji aplikacji webowych.
Podstawy protokołu HTTP
HTTP to protokół komunikacyjny oparty na modelu klient-serwer, który stanowi fundament współczesnego internetu. Jego działanie opiera się na prostym, ale niezwykle skutecznym mechanizmie żądanie-odpowiedź. Dla programisty zrozumienie tego procesu jest kluczowe, ponieważ model ten znajduje zastosowanie w niemal każdej współczesnej aplikacji.
Przykładowo, otwierając stronę internetową w przeglądarce, przeglądarka wysyła żądanie do serwera, prosząc o zawartość strony. Serwer przetwarza to żądanie i zwraca odpowiedź, która zawiera m.in. kod HTML strony widocznej na ekranie. Dzięki wydajności protokołu HTTP cały proces odbywa się niemal natychmiastowo, co przekłada się też na jego popularność.
Jak działa protokół HTTP
1. Klient wysyła żądanie do serwera (request) – Komunikacja rozpoczyna się od wysłania żądania HTTP przez klienta, którym najczęściej jest przeglądarka internetowa (ale oczywiście może być dowolny system). Żądanie zawiera najważniejsze informacje, takie jak:
- Adres URL – wskazanie, do jakiego zasobu odwołuje się klient, np. strony HTML, obrazu czy pliku JSON.
- Parametry – dodatkowe dane, które precyzują zapytanie (np. filtry wyszukiwania).
- Metoda HTTP – określenie typu operacji, np. GET, POST, PUT.
- Ciało zapytania – opcjonalne dane, przesyłane np. w formularzach.
- Nagłówki – szczegóły techniczne, takie jak typ akceptowanych danych czy autoryzacja.
2. Serwer przetwarza żądanie – Po otrzymaniu żądania serwer analizuje je i podejmuje odpowiednie działanie. W zależności od jego treści może np.:
- wysłać żądany zasób,
- wygenerować dane na podstawie zapytania,
- zwrócić błąd, jeżeli żądanie jest nieprawidłowe lub zasób nie istnieje.
3. Serwer wysyła odpowiedź do klienta (response) – Serwer przesyła odpowiedź HTTP, która zawiera:
- Kod odpowiedzi – informujący o wyniku operacji, np. 200 OK, 404 Not Found.
- Ciało odpowiedzi – dane, takie jak zawartość strony, wyniki wyszukiwania lub plik.
- Nagłówki odpowiedzi – dodatkowe informacje, np. o typie zwróconych danych czy zasadach buforowania.
Adres URL
http://piotr:pass@www.uprogramisty.pl:80/test-sciezka?strona=1¶metr2=tekst#Swagger
protokół (ang. scheme) – Określenie protokołu, dzięki którego następuje komunikacja między klientem a serwerem.. Najczęściej będzie to http lub https.
użytkownik (ang. user) – Nazwa użytkownika do uwierzytelnienia. Przekazywanie tych danych w ten sposób nie jest zalecane. Są lepsze i bezpieczniejsze sposobu.
hasło (ang. password) – Hasło do uwierzytelnienia. Przekazywanie tych danych w ten sposób nie jest zalecane. Są lepsze i bezpieczniejsze sposobu.
serwer (ang. host) – Nazwa domeny internetowej lub adresu IP np. 192.168.123.112.
port – Dla danej domeny serwer może obsługiwać wiele portów. W przypadku protokołu HTTP domyślnie wykorzystywany jest port 80, natomiast dla HTTPS jest to port 443.
/ścieżka (ang. /path) – Określenie konkretnego zasobu do którego chcemy się odwołać.
?parametry (ang. ?query) – Zawiera dodatkowe informacje do określenia konkretnego interesującego nas zasobu. Sekcja parametrów zapytania zaczyna się od znaku ? i zawiera pary klucz-wartość. W naszym powyższym przykładzie będzie to parametr o nazwie strona z wartością 1 oraz parametr parametr2 z wartością tekst.
#fragment – Jest to fragment url, który odnosi się do określenia konkretnego miejsca na stronie. Fragment ten zaczyna się od znaku #. Jak wejdziemy na taki adres to strona automatycznie przekieruje nas do odpowiedniego fragmentu na stronie.
Metody HTTP
Protokół HTTP oferuje zestaw metod, które definiują rodzaj operacji wykonywanej na zasobie. Każda metoda ma swoją specyfikę i zastosowanie, co pozwala na efektywną komunikację między klientem a serwerem.
Najczęściej wykorzystywanymi metodami HTTP są GET, POST, PUT i DELETE. Metoda GET służy do pobierania danych bez modyfikacji zasobów, co sprawia, iż jest idealna do przeglądania stron internetowych lub pobierania plików. Z kolei POST umożliwia przesyłanie danych na serwer, np. podczas wysyłania formularzy czy tworzenia nowych zasobów.
Metoda PUT jest używana do nadpisywania istniejącego zasobu lub tworzenia go od podstaw, jeżeli jeszcze nie istnieje. Jest często stosowana w operacjach aktualizacji danych w API RESTful. Z kolei DELETE umożliwia trwałe usunięcie zasobu z serwera, zapewniając skuteczne zarządzanie zbędnymi lub przestarzałymi danymi w aplikacji.
GET | Niedozwolone | Opcjonalne | Tak | Pobiera zasób z serwera bez modyfikacji. |
POST | Dozwolone | Opcjonalne | Nie | Tworzy nowy zasób lub wykonuje akcję. |
PUT | Dozwolone | Opcjonalne | Nie | Nadpisuje cały zasób na serwerze. |
PATCH | Dozwolone | Opcjonalne | Nie | Aktualizuje częściowo istniejący zasób. |
DELETE | Niedozwolone | Opcjonalne | Nie | Usuwa istniejący zasób z serwera. |
HEAD | Niedozwolone | Niedozwolone | Tak | Pobiera tylko nagłówki odpowiedzi. |
TRACE | Niedozwolone | Niedozwolone | Nie | Debugowanie ścieżki komunikacji. |
OPTIONS | Niedozwolone | Opcjonalne | Nie | Uzyskuje informacje o dostępnych metodach. |
*cache – umożliwia zmniejszenie czasu odpowiedzi serwera poprzez przechowywanie wcześniej pobranych danych. Podczas pierwszego żądania dane są pobierane z serwera i zapisywane w pamięci podręcznej (cache). Kolejne żądania do tego samego zasobu mogą korzystać z zapisanych danych w cache, zamiast ponownie odwoływać się do serwera, co znacząco skraca czas odpowiedzi.
Idempotentność
Idempotentność oznacza, iż niezależnie od liczby wykonanych żądań do tego samego zasobu, efekt operacji na serwerze pozostanie taki sam, a odpowiedź będzie identyczna (o ile zasób nie zostanie zmieniony przez inne żądania). Idempotentne są metody HTTP takie jak GET, HEAD, PUT, OPTIONS, TRACE i DELETE.
Metoda POST nie jest idempotentna, ponieważ służy głównie do tworzenia nowych zasobów lub obiektów. Każde jej wywołanie powinno skutkować utworzeniem nowego zasobu, co oznacza, iż wielokrotne wywołanie tego samego żądania prowadzi do różnych efektów.
Ciało zapytania i odpowiedzi (body)
Ciało zapytania i odpowiedzi umożliwia przesyłanie bardziej złożonych danych pomiędzy klientem a serwerem. Mogą to być struktury danych, takie jak JSON czy XML, pliki lub inne formaty dostosowane do potrzeb aplikacji.
Jednym z najczęściej używanych formatów jest JSON. Jest to prosty, czytelny i łatwy do zrozumienia format, który zyskał ogromną popularność właśnie dzięki swojej prostocie. choćby osoby nietechniczne mogą łatwo zrozumieć jego strukturę, co czyni go idealnym wyborem w wielu projektach. JSON pozwala na przesyłanie danych w postaci:
- Obiektów (oznaczanych nawiasami klamrowymi {}), które zawierają pary klucz-wartość.
- List obiektów (oznaczanych nawiasami kwadratowymi []), które grupują wiele obiektów w jedną strukturę.
Kody odpowiedzi
Rozróżniamy 5 kategorii kodów odpowiedzi HTTP:
- 1xx Informacyjne – Wskazują, iż żądanie zostało pomyślnie odebrane, a jego dalsze przetwarzanie trwa.
- 2xx Sukces – Oznaczają, iż żądanie zostało pomyślnie zrealizowane.
- 3xx Przekierowanie – Informują, iż klient musi wykonać dodatkową akcję, aby zakończyć proces.
- 4xx Błąd po stronie klienta – Oznaczają, iż żądanie nie mogło zostać przetworzone z powodu błędu po stronie klienta.
- 5xx Błąd po stronie serwera – Informują o problemach, które wystąpiły po stronie serwera i są niezależne od działań klienta.
Przykłady
100 | Continue | Wskazuje, iż żądanie zostało częściowo przetworzone i można kontynuować. |
101 | Switching Protocols | Serwer akceptuje zmianę protokołu na żądanie klienta. |
200 | OK | Żądanie zostało pomyślnie przetworzone. |
201 | Created | Nowy zasób został pomyślnie utworzony. |
202 | Accepted | Żądanie zostało przyjęte do realizacji, ale jeszcze nie zostało wykonane. |
204 | No Content | Żądanie zakończyło się sukcesem, ale nie ma treści w odpowiedzi. |
300 | Multiple Choices | Istnieje wiele opcji dla żądanej zasoby, klient musi wybrać jedną. |
301 | Moved Permanently | Zasób został trwale przeniesiony pod nowy adres URL. |
302 | Found | Zasób tymczasowo dostępny pod innym adresem URL. |
304 | Not Modified | Zasób nie został zmieniony od ostatniego żądania klienta. |
400 | Bad Request | Żądanie jest nieprawidłowe lub nie może zostać zrozumiane przez serwer. |
401 | Unauthorized | Brak autoryzacji, wymagane uwierzytelnienie użytkownika. |
403 | Forbidden | Dostęp do zasobu jest zabroniony. |
404 | Not Found | Żądany zasób nie został znaleziony na serwerze. |
405 | Method Not Allowed | Metoda żądania nie jest dozwolona dla danego zasobu. |
409 | Conflict | Konflikt w żądaniu, uniemożliwiający jego przetworzenie. |
500 | Internal Server Error | Serwer napotkał nieoczekiwany błąd podczas przetwarzania żądania. |
501 | Not Implemented | Serwer nie obsługuje żądanej funkcji. |
Rola nagłówków w protokole HTTP
Nagłówki w protokole HTTP odgrywają kluczową rolę w komunikacji pomiędzy klientem a serwerem. Stanowią one dodatkowe informacje dołączane zarówno do żądań, jak i odpowiedzi, które precyzują sposób przesyłania i interpretacji danych. Dzięki nim HTTP zyskuje na elastyczności, umożliwiając obsługę zróżnicowanych scenariuszy, takich jak autoryzacja, kontrola buforowania czy obsługa różnych formatów danych.
Przykład nagłówków dla żądania HTTP (request)
GET /api/products HTTP/1.1 Host: www.example.com Accept: application/json Authorization: Bearer abc123xyz User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)Wyjaśnienie nagłówków w żądaniu:
- Host: www.example.com – wskazuje, na którym serwerze znajduje się zasób.
- Accept: application/json – klient oczekuje danych w formacie JSON.
- Authorization: Bearer abc123xyz – zawiera token uwierzytelniający użytkownika.
- User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) – informuje o przeglądarce i systemie operacyjnym klienta.
Przykład nagłówków dla odpowiedzi HTTP (response)
HTTP/1.1 200 OK Content-Type: application/json Content-Length: 125 Cache-Control: no-cache Date: Mon, 29 Jan 2025 12:00:00 GMTWyjaśnienie nagłówków w odpowiedzi:
- Content-Type: application/json – dane zwrócone w formacie JSON.
- Content-Length: 125 – długość zwracanych danych wynosi 125 bajtów.
- Cache-Control: no-cache – wyłącza buforowanie danych.
- Date: Mon, 30 Dec 2024 12:00:00 GMT – data i czas wygenerowania odpowiedzi.
Bezpieczeństwo w HTTP: HTTP vs HTTPS
Bezpieczeństwo w komunikacji sieciowej to jedno z najważniejszych zagadnień, szczególnie w erze, gdy większość danych przesyłanych między klientami a serwerami zawiera poufne informacje. Protokół HTTP, w swojej podstawowej wersji, nie zapewnia szyfrowania danych, co czyni przesyłane informacje podatnymi na przechwycenie przez osoby trzecie. Tutaj pojawia się HTTPS, który rozwiązuje te problemy, oferując bezpieczną komunikację.
HTTP – Brak szyfrowania
HTTP działa jako protokół tekstowy, co oznacza, iż wszystkie dane przesyłane między klientem a serwerem są przesyłane w formie otwartego tekstu:
- Brak szyfrowania – Dane mogą zostać przechwycone i odczytane przez osoby trzecie.
- Brak weryfikacji tożsamości – Nie ma gwarancji, iż połączenie odbywa się z prawdziwym serwerem, co otwiera drogę do ataków typu Man-in-the-Middle (MitM).
- Niebezpieczny dla poufnych danych – Przesyłanie loginów, haseł czy danych osobowych przez HTTP jest bardzo ryzykowne.
HTTPS – Bezpieczne rozszerzenie HTTP
HTTPS to ulepszona wersja HTTP, która wykorzystuje protokół SSL/TLS (Secure Sockets Layer / Transport Layer Security) do szyfrowania komunikacji:
- Szyfrowanie danych – Wszystkie dane przesyłane między klientem a serwerem są zaszyfrowane, co uniemożliwia ich przechwycenie i odczytanie przez osoby trzecie.
- Weryfikacja tożsamości – Certyfikaty SSL/TLS potwierdzają, iż komunikacja odbywa się z zaufanym serwerem.
- Integralność danych – Szyfrowanie chroni dane przed ich modyfikacją podczas przesyłania.
- Ochrona danych – Szyfrowanie chroni dane użytkowników przed ich przechwyceniem i wykorzystaniem w nieuczciwy sposób.
Wersje protokołu HTTP
Protokół HTTP przeszedł przez kilka wersji, z których każda wprowadzała nowe funkcjonalności i poprawki:
- HTTP/0.9 (1991) – Pierwsza wersja protokołu, która była bardzo prosta i ograniczona.
- HTTP/1.0 (1996) – Pierwsze oficjalne wydanie. Wprowadzono możliwość wysyłania nagłówków oraz obsługę różnych metod.
- HTTP/1.1 (1997) – Wprowadzono trwałe połączenia (persistent connections), co pozwala na wielokrotne użycie tego samego połączenia TCP dla wielu żądań.
- HTTP/2 (2015) – Umożliwiono równoczesne wysyłanie wielu żądań przez jedno połączenie TCP (multiplexing), co znacznie przyspiesza ładowanie stron.
- HTTP/3 (2022) – Opiera się na protokole QUIC, który ma na celu dalsze zwiększenie wydajności poprzez eliminację opóźnień związanych z połączeniami TCP.
Protokół HTTP w Spring Boot
W Spring Boot również korzystamy z protokołu HTTP. Tworząc usługę opartą na API, komunikacja z nią odbywa się właśnie dzięki tego protokołu. W nowoczesnych aplikacjach, gdzie mamy model klient-serwer, aplikacje tworzone w Spring Boot często bazują na HTTP, co pozwala na łatwą wymianę danych między różnymi systemami.
Aby wystawić usługę w Spring Boot, wystarczy utworzyć klasę w Javie i dodać do niej odpowiednie adnotacje, takie jak @RestController oraz @RequestMapping. Dzięki temu aplikacja będzie mogła obsługiwać żądania HTTP, a klienci będą mieli dostęp do wystawionych zasobów. Na przykład:
import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/users") class UserController { private final UserService userService; UserController(UserService userService) { this.userService = userService; } @GetMapping("/{id}") public ResponseEntity<User> getUser(@PathVariable Long id) { User user = userService.findById(id); if (user == null) { return ResponseEntity.status(HttpStatus.NOT_FOUND).build(); } return ResponseEntity.ok(user); } @PostMapping public ResponseEntity<User> createUser(@RequestBody User user) { User createdUser = userService.save(user); return ResponseEntity.status(HttpStatus.CREATED).body(createdUser); } }W powyższym przykładzie kontroler obsługuje żądania GET i POST:
- GET: Pobiera użytkownika na podstawie przekazanego ID.
- POST: Tworzy nowego użytkownika na podstawie danych przesłanych w ciele żądania (JSON).
Opis adnotacji wykorzystanych w przykładzie:
- @RestController – definiuje klasę jako kontroler REST.
- @RequestMapping – mapuje ścieżkę do kontrolera. Jest to ścieżka, która zostaje dodana przed każdym żądaniem w tej klasie.
- @GetMapping – obsługuje żądania HTTP GET.
- @PostMapping – obsługuje żądania HTTP POST.
- @PathVariable – wyciąga zmienne z URL. Zmienne te w ścieżce opisujemy dodając znaki {}.
- @RequestBody – mapuje ciało żądania HTTP na obiekt Javy.
Testowanie żądań HTTP
Testowanie żądań HTTP jest kluczowym elementem pracy każdego programisty, szczególnie podczas tworzenia i debugowania API. Do tego celu możemy użyć narzędzi takich jak Postman i cURL, które umożliwiają łatwe wysyłanie i analizowanie żądań. Dodatkowo, dla lepszej dokumentacji i testowania, możemy wystawić interfejs API w formacie Swagger.
Postman
Postman to popularne narzędzie o interfejsie graficznym, które pozwala na wysyłanie żądań HTTP (GET, POST, PUT, DELETE i innych) oraz analizowanie odpowiedzi serwera. Dzięki intuicyjnemu interfejsowi, Postman jest szczególnie przydatny dla początkujących programistów oraz w pracy zespołowej. Możesz tworzyć kolekcje zapytań, testować API i generować dokumentację.
Postman oficjalny poradnik (język angielski). Na stronie Postmana znajduje się podstrona, na której przedstawiono, jak używać tego narzędzia. Według mnie, program jest na tyle intuicyjne, iż chwilę z nim popracujesz i powinieneś się go nauczyć. A jak czegoś nie będziesz wiedział, to dopiero wtedy będziesz szukał jak to zrobić.
cURL
cURL to narzędzie wiersza poleceń, które pozwala na wysyłanie żądań HTTP bezpośrednio z terminala. Jest niezwykle lekkie i idealne do automatyzacji oraz testowania API w środowiskach skryptowych. Przykład prostego żądania GET dzięki cURL:
curl -X GET https://api.example.com/resourceNatomiast jeżeli chcemy przesłać dane dzięki żądania POST w formacie JSON, używamy następującej składni:
curl -X POST https://api.example.com/resource \ -H "Content-Type: application/json" \ -d '{"key":"value"}'Swagger
Swagger to narzędzie, które pozwala na automatyczne generowanie dokumentacji API oraz interfejsu do testowania endpointów. W Spring Boot możesz łatwo zintegrować Swaggera dzięki biblioteki Springfox lub Springdoc OpenAPI. Po wdrożeniu Swaggera, dostępny jest panel użytkownika, w którym można przeglądać, testować i analizować wszystkie dostępne endpointy API.
Więcej na temat samego narzędzia pisałem we wpisie jak stworzyć dobre portfolio programisty.
Podsumowanie
W tym wpisie szczegółowo wyjaśniłem, czym jest protokół HTTP, omówiłem jego podstawy i zasady działania, a także pokazałem, jak jego znajomość przekłada się na tworzenie aplikacji webowych. HTTP to fundament komunikacji klient-serwer, który umożliwia efektywną wymianę danych, budowę wydajnych API i rozwój skalowalnych rozwiązań.
Znajomość HTTP jest kluczowa dla wszystkich programisty, niezależnie od poziomu zaawansowania. Opanowanie jego zasad otwiera drzwi do projektowania nowoczesnych, dynamicznych aplikacji, które są nieodłączną częścią współczesnego internetu.