Podstawy HTTP (Hypertext Transfer Protocol)


Zabierając się za programowanie webowe, w obojętnie jakiej technologi, tak też i w Java, nie sposób uniknąć tematu tego protokołu. Kwestia jest taka, że umożliwia on komunikację, wymianę danych, oraz w ogóle korzystanie z aplikacji uruchomionych na serwerach w Internecie. Aplikacje te wystawiają swoje API (ang. application programming interfaces), które przystosowane są do komunikacji z klientami (zwykle przeglądarką internetową) poprzez właśnie ten protokół. Jeżeli brakuje ci takiego obrazka w głowie jak to wygląda, to polecam zerknąć sobie na ten materiał. Jest to takie dość fajnie obrazujące, przystępne wprowadzenie do Internetowych API, które mi się spodobało. No a jeśli samo określenie API ma dla ciebie nieco rozmyte znaczenie, to na forum u Pana Zelenta ktoś dość obrazowo to opisał, więc jeżeli potrzebujesz dodatkowego wyjaśnienia: go there.

Protokół HTTP powstał w zamyśle do przesyłania dokumentów hipertekstowych, czyli składających się z niezależnych zamkniętych części – leksji, które są połączone ze sobą poprzez odnośniki/linki – hiperłącza. Opracowanie protokołu ściśle łączy się z HTML, który jest właśnie hipertekstowy. Na początku protokół HTTP miał tylko jedną metodę GET, pobierającą z serwera WWW dokument w HTML. Z resztą ciągle tak jest, że przeglądarka odświeżając się domyślnie wysyła zapytanie z metodą GET, pobierając aktualne dane.

Praca protokołu HTTP opiera się o cykl żądań od strony klienta, np. przeglądarki, oraz odpowiedzi ze strony serwera. HTTP jest protokołem warstwy aplikacji, tj. jego żądania i odpowiedzi bazują na protokole warstwy transportowej TCP i protokole służącym identyfikacji sieci – IP.

Istotne jest, że jest to protokół bezstanowy, tj. nie przechowuje informacji o poprzednich transakcjach. Każde żądanie płynące z widoku jest niezależne od siebie i nie pozostawia po sobie żadnych informacji. Z tego też powodu, aby utworzyć i utrzymać przez jakiś określony czas sesję z np. logowaniem i wylogowaniem, serwisy internetowe częstują swoich klientów ciasteczkami, po których są oni następnie identyfikowani, przykładowo pomiędzy zalogowania.

Takim podstawowym dla mnie elementem, rozróżniającym request klienta od respons z serwera, jest to że zapytanie zawiera w sobie metodę określającą co ma się stać, odpowiedź zaś zawiera status mówiący o tym co się stało. Same zaś żądania i odpowiedzi są wiadomościami przyjmującymi pewien ustandaryzowany format. 

Żądanie HTTP

Przykład:

$ curl -I -v https://dev-wannabe.pl/kategorie/
> HEAD /kategorie/ HTTP/1.1
> Host: dev-wannabe.pl
> User-Agent: curl/7.52.1
> Accept: */*
>

Zapytania do serwisów zwykle wysyłane są przez przeglądarki, ale można też używać innych narzędzi, takich jak Postman, czy konsolowy Curl, z którego ja skorzystałem. Znak ‘>‘, to kierunek wysyłki, tj. w stronę serwera. Pierwsza linia wydaje się najistotniejsza i jest minimum do tego aby serwer ewentualnie odpowiedział.

HEAD To metoda, najpopularniejsze z nich to: GET – pobranie zasobu, POST – utworzenie, PUT – aktualizacja, DELETE – usunięcie. Co prawda w swoim zapytaniu użyłem HEAD ale  choć jest jak GET, to jeżeli go użyjesz serwer nie zwróci zawartości dokumentów w ciele, a jedynie informację o nich. Raczej się więc go normalnie nie stosuje, ale gdy coś testujesz w konsoli, to możesz nie chcieć ekranów kodu z formularzy.
/kategorie  Ścieżka do zasobu po adresie głównym domeny – część path adresu URL. Spotkałem się z określeniem URI, ale URI to raczej taki nadzbiór, tzn. unikalny identyfikator zasobu, który zawiera jednak w sobie również URL – zerknij na wiki.
HTTP/1.1 Wersja protokołu HTTP
Host
User-Agent
Accept: */*
To tak zwane nagłówki (ang. headers). Może być ich więcej niż te trzy. Są to metadane, czyli informacje na temat informacji, tj. requestu oraz jego zawartości. Mogą to być przykładowo informacje na temat formatu dokumentu transportowanego w ciele zapytania oraz jego długości. W przypadku odpowiedzi z serwera mogą to być informacje dotyczące jego typu, lokalizacji, czy daty wygenerowanej odpowiedzi.
HOSTS – adres domeny bez którego możesz nie otrzymać właściwej  odpowiedzi z serwera. Adres URL, który wpisałeś w przeglądarce w pierwszej kolejności zostanie przerobiony na adres IP konkretnego serwera, a na nim może istnieć wiele różnych domen, w tym i twoja, tzw. wirtualny hosting. Informacja więc, o którą domenę idzie pobierana jest z requestu.
USER-AGENT – typ aplikacji klienckiej, może to być nazwa przeglądarki, w moim przypadku jest to programik curl. Jeżeli żądanie go nie zawiera, to może być odebrane jako podejrzane.
ACCEPT:*/* – typ MIME akceptowanych dokumentów, np. text/html. W tym przypadku zaakceptowane będzie wszystko co wróci.
W gwoli ścisłości tych nagłówków zwykle się nie pisze w zapytaniach, po prostu klient, np. przeglądarka je ustawia, aczkolwiek można mieć 
wpływ na to co ustawi.
CIAŁO(body) – opcjonalne
Ciało od nagłówków, które są powyżej, oddzielone jest pustą linią i to zapytanie go nie posiada. Może ono zawierać informacje, np. w postaci formularza z nowymi wartościami pól, które zostaną utrwalone w modelu danego systemu/aplikacji. Istnienie ciała zależy od metody oraz od tego czy jest to zapytanie do serwera, czy odpowiedź. Przykładowo zapytanie z metodą GET ciała raczej nie będzie posiadać, natomiast może je zawierać odpowiedź.

Odpowiedź HTTP

Przykład:

< HTTP/2 200 
< date: Wed, 24 Oct 2018 08:51:42 GMT
< server: Apache
< content-type: text/html; charset=UTF-8
HTTP/2
Wersja protokołu HTTP użytego w odpowiedzi
200 Status HTTP odpowiedzi z serwera. Występuje pięć głównych kodów grup statusów:

1XX – kody informacyjne:
100 – kontynuuj, 101 – zmiana protokołu, 110 – przekroczono czas połączenia, 111 – serwer odrzucił połączenie.

2XX – kody powodzenia:
200 – przetworzono poprawnie, 201 – przetworzono i utworzono zasób,  202 – zapytanie przyjęto ale jeszcze nie zrealizowano, 204 – brak zawartości w ciele odpowiedzi.

3XX – kody przekierowania:
300 – wiele możliwości obsłużenia zapytania, 301 – zasób trwale przeniesiony.

4XX – kody błędu po stronie klienta:
400 – nieprawidłowe zapytanie, 401 – nieautoryzowany dostęp, 403 – wymaga uwierzytelnienia, 404 – nie odnaleziono zasobu.

5XX – kody błędu po stronie serwera:
500 – wewnętrzny błąd serwera, 502 – serwer pełniący rolę bramy, pośredniczący, otrzymał niepoprawną odpowiedź z serwera nadrzędnego,
503 – usługa niedostępna, serwer został przeciążony.

date:
server:
content-type:
Nagłówki, w tym ostatni informujący o formacie i stronie kodowej dokumentu, którego zapytanie dotyczyło. Sam dokument jednak nie został dołączony do ciała odpowiedzi, bo użyłem metody HEAD w zapytaniu.

Jako uzupełnienie tematu protokołu HTTP, w tym dokładniejszy opis nagłówków lub rozbity na części i porządnie opisany URL, możesz zerknąć na artykuł w samouczku Marcina Pietraszka.

Request i co dalej?

Taka pojedyncza akcja – request HTTP, zwykle oddziałuje w taki sposób na systemy, w tym oparte o Javę i Spring MVC, że zostaje pobrany, utworzony, usunięty, bądź zmieniony zapis, w określonej kolumnie, określonego wiersza, określonej tabeli (relacji), w jakiejś relacyjnej bazie danych. Zazwyczaj, a jeżeli używasz Spring MVC, to po prostu tak jest, że proces ten odbywa się w oparciu o wzorzec Model View Controller. Zakłada on, że dane napływające z widoku są oddzielone od warstwy bazy danych, czyli modelu, kontrolerem. Trochę o samym MVC, ale nie tylko, znajdziesz w poprzednim moim wpisie.

Java jest językiem obiektowym, bazy danych zaś zwykle relacyjne. Gdy uczysz się programować z wykorzystaniem Spring, szybko dostrzegasz, że mapowanie obiektowo-relacyjne, czyli odwzorowywanie danych obiektowego systemu w relacyjnej bazie danych, jest immanentną częścią programowania w tej technologii. Klasa jest mapowana na tabelę, obiekty są jej wierszami, a pola obiektów kolumnami.

Zatwierdzając więc w przeglądarce zmianę jakiejś wartości na inną, wysłane zostaje do kontrolera żądanie HTTP, z odpowiednią metodą. Zawiera ono w swoim ciele informację z widoku w formacie JSON lub dokumentu HTML, o zmodyfikowanym stanie danego obiektu. W dalszej kolejności zmiany na określonych polach są nadpisywane w bazie, a następnie obiekty z nowymi wartościami w brzuszku, wracają poprzez kontroler, z powrotem na widok.

No i to by było na tyle, zapraszam cię do kolejnych wpisu, w jednym z nich postaram się opisać i samemu zrozumieć pojedynczy cykl żądania klienta i odpowiedzi serwera.

Warning! Tego nie pisał programista, ale dev-wannabe. Jak coś poknociłem, chętnie się o tym dowiem.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *