"Request rzucił mi pięćsetkę", czyli o komunikacji http

comunication http web
man wearing brown suit jacket mocking on white telephone

Z pewnością obiło Ci się o uszy kiedyś, że ktoś wysyła "request". Czym jest owy "request"? Kto go wysyła i właściwie to do kogo? O co chodzi, gdy ktoś mówi "dostałem 500"? Spróbuję to wyjaśnić w prostych słowach.

Czym jest komunikacja?

Pojęcia "request" i "response" pojawiają się najczęściej w kontekście komunikacji. Komunikacja zazwyczaj wymaga conajmniej dwóch rozmówców. Załóżmy, że rozmawiasz ze swoim kolegom z pracy, wasz dialog wygląda mniej więcej tak:

Ty: Hej, czy możesz mi podać nazwy naszych klientów?

Kolega: Jasne, to firma A, firma B i firma C.
Ty: Czy możesz mi podać numer kontaktowy do firmy C?
Kolega: Oczywiście, 111 222 333.

Gratuluję, właśnie przeprowadziłeś komunikację dwukierunkową w modelu request-response! Komunikacja dwukierunkowa oznacza, że dla każdego Twojego żądania ("podaj nazwy klientów", "podaj numer kontaktowy"), Twój rozmówca potwierdził, że je otrzymał ("jasne", "oczywiście") a następnie odpowiedział danymi o które prosiłeś ("firma A, firma B....", "111 222 333").

Na analogicznej zasadzie działają serwisy internetowe. Gdy w pasku przeglądarki wpisujesz
linkedin.com/in/rafał-orłowski-90721490
Mówisz mniej więcej: "Hej, Linkedin, podaj mi dane użytkownika rafał-orłowski-90721490". Różnica jest tak, że mówisz to w języku maszyn a nie w języku ludzi. I jak to ma się do "requestu"?

Czym jest żądanie?

Wpisując cokolwiek w pasek przeglądarki wysyłasz "request" typu GET pod podany adres URL (o tym czy jest URL za chwilę). Czym jest "typ requestu"? Jest to sposób na wyrażenie Twoich intencji. Przeglądarki internetowe są pewnego rodzaju "klientem http", który ma za zadanie uprościć komunikację między człowiekiem a serwisami internetowymi (np: stronami www). Na potrzeby tego artykułu nie będziemy zagłębiać się w to, czym jest protokół "http". W telegraficznym skrócie: to techniczna specyfikacja, opisująca w jaki sposób usługi internetowe mogą się ze sobą komunikować. Podobnie jak standard GSM, który opisuje w jaki sposób komunikują się dwa telefony. Albo jak przepisy ruchu drogowego opisujące w jaki sposób przemieścić się autem z punku A do punktu B w bezpieczny sposób.

Wracając do typów "requestów", kilka podstawowych to:
- GET - daj mi dane. Na przykład pokaż mi profil użytkownika X.
- POST - wysyłam Ci nowe dane, odbierz je. Za każdym razem wstawiając nowe zdjęcie na instagrama, wysyłasz POST z załączonym plikiem graficznym. 

- UPDATE - wysyłam Ci aktualizację danych, Przykładowo: zmieniłaś nazwisko po ślubie i chcesz je zaktualizować w swoich mediach społecznościowych.

- DELETE - skasuj dane. Masz dość social mediów - usuwasz swój profil!

Dane które wysyłamy mogą przybierać różną formę. Czasem może to być zwykły tekst, czasem obraz (plik w formacie .jpg, .png czy w innym formacie graficznym), a czasem ustrukturyzowane dane w jednym z popularnych formatów danych, np: JSON czy XML ale o formatach danych innym razem.

Skoro wiemy już co możemy wysłać to teraz zastanówmy się gdzie możemy wysłać nasze żądania. Tak naprawdę naszym adresatem może być dowolna "usługa internetowa" (czasem nazywany "serwisem internetowym" - to to samo). Tak, tak, kolejna trudna nazwa, spokojnie już wyjaśniam. Pamiętasz wcześniejszy przykład, z wpisywaniem
linkedin.com/in/rafał-orłowski-90721490
w pasku przeglądarki? To tak zwany URI (unified resource identifier), możesz też spotkać określenie URL (unified resource locator), różnica między tymi określeniami jest bardzo subtelna i raczej filozoficzna niż techniczna, dlatego na potrzeby tego artykułu przyjmijmy uproszczenie, że oba określenia są tożsame. Jeśli jesteś bardzo dociekliwy i chcesz poznać więcej szczegółów zajrzyj na przykład tu.
Usługa internetowa to tak naprawdę dowolna "rzecz" która kryje się pod pewnym adresem (np: linkedin.com).

Czym jest odpowiedź?

Serwis do którego wysyłamy żądnie, zawsze nam odpowiada. Odpowiedź składa się z dwóch kluczowych elementów: statusu odpowiedzi i danych. Wróćmy do przykładu naszej rozmowy z kolegą:

Ty: Hej, czy możesz mi podać nazwy naszych klientów?
Kolega: Jasne, to firma A, firma B i firma C.
W tym przypadku nasze żądanie ("podaj nazwy klientów") zostało przetworzone poprawnie ("jasne") i zwrócono nam dane ("firma A, firma B i firma C"). Gdybyśmy otrzymali odpowiedź:

"Nie mogę. Tylko kierownik działu może otrzymać pełną listę klientów"
to nasze żądanie nie zostało obsłużone poprawnie ("nie mogę") ale nasz kolega był na tyle miły, że otrzymaliśmy odpowiedź: "Tylko kierownik działu może otrzymać pełną listę klientów". Mógł być niemiły i odpowiedzieć tylko "Nie mogę".
W naszym "świecie http" za powiedzenie "jasne, tu są dane" albo "niestety, nie mogę" odpowiedzialne są statusy. Statusy są to 3 cyfrowe wartości z zakresu 100-599 - dość dziwny przedział, prawda?

Już tłumaczę skąd taki nietopowy zakres wartości. Pierwsza cyfra (1,2,3,4 lub 5) określa "kategorię status", mianowicie:

1xx - przyjęto wiadomość, przetwarzam, nie wiem kiedy skończę. W praktyce bardzo rzadko spotykane.

2xx - sukces! Tych statusów chcielibyśmy widzieć najwięcej. Znaczą, że udało się zrobić dokładnie to co chcieliśmy zrobić.

3xx - przekierowano. Czyli taki trochę sukces ale nasze żądanie musiało zostać przekierowane w inne miejsce, i czy się finalnie uda czy nie to już się dowiemy w odpowiedzi z tego innego miejsca. To skomplikowane, żeby nie wchodzić w szczegóły, uznajmy, że to takie "żądnie jest ok, przekierowano je na inny URL". W praktyce wykorzystywane w bardziej złożonych systemach, do obsługiwania bardziej nietypowych scenariuszy komunikacji.

4xx - nie udało się przetworzyć Twojego żądania. Przesłano nieprawidłowe dane. W praktyce oznacza to, że wysłałeś niepoprawny request.
5xx - nie udało się przetworzyć Twojego żądania, jednak tym razem to błąd po stronie serwisu do którego wysłałeś request. Innymi słowy: Twój request wydaje się być ok, ale serwis z jakiegoś powodu nie był w stanie zrobić tego o co go prosiłeś. Odpowiedzi ze statusem 5xx są zazwyczaj najbardziej tajemnicze.
Wszystkie standardowe statusy wraz z wyjaśnieniami mogą być znalezione na wikipedii.

Jak wspomniałem wcześniej, poza statusami w odpowiedzi otrzymujemy (zazwyczaj) również dane. Tu, podobnie jak w przypadku "requestu" nie ma jednej odpowiedzi na pytanie "jakie dane". W zależności od usługi z którą się komunikujemy, może to być plik (dźwięk, obraz, dokument), tekst (np: treść tego artykułu), lub dane ustrukturyzowane w jendym z popularnych formatów (np: JSON, XML).

Wracając do przykładu "Hej, czy możesz mi podać nazwy naszych klientów?", kolejne odpowiedzi mogą być postrzegane jako:

"Jasne, to firma A, firma B i firma C." - status odpowiedzi: 200 (ok), dane: "firma A, firma B i firma C".

"Nie mogę. Tylko kierownik działu może otrzymać pełną listę klientów" - status odpowiedzi: 403 ("zabronione", ang. "forbidden"), dane: "Tylko kierownik działu może otrzymać pełną listę klientów".

"Nie mogę." - status odpowiedzi: 500 ("wewnętrzny błąd serwera", ang "Internal Server Error"), brak jakichkolwiek danych.

Jak to wszystko połączyć?

To wszystko może brzmieć bardzo abstrakcyjnie ale spróbujmy to jakoś podsumować. Wyobraź sobie, że z jakiegoś dziwnego powodu internet nagle przestaje istnieć (może to być atak kosmitów którzy zagłuszyli sygnały na całym świecie, małe, podstępne rekino-trole które poprzegryzały wszystkie kable albo dowolny inny absurdalny powód). Wyobraź sobie również, że wszystkie gigantyczne portale internetowe (Google, LinkedIn, Instagram etc.) nadal chcą prowadzić swoją dotychczasową działalność. I ostatnie założenie, najbardziej absurdalne ale idealnie pasujące do naszego artykułu: portale internetowe nie będą świadczyć swoich usług przez internet (bo nie istnieje) ale przez pocztę. Taką tradycyjną. Z kopertami, listami, listonoszami na rowerach, skrzynkami pocztowymi poustawianymi w różnych częściach miasta.... Tak więc Instagram przestaje być "portalem internetowym" a zaczyna być "portalem... pocztowym?", witamy w nowej rzeczywistości!

Właśnie zrobiłeś sobie cudowne selfie swoim odkopanym na strychu Polaroidem (dla młodszych czytelników: to taki "instax" dla starych ludzi) i chcesz je oczywiście wstawić na Instagrama. Tak, tego "pocztowego Instagrama". Bierzesz więc kopertę, adresujesz ją: "Instagram. Menlo Park, California, US", do koperty wkładasz swoje zdjęcie i wrzucasz do skrzynki pocztowej. Po kilku dniach otrzymujesz list od Instagrama, którego treść brzmi: "dziękujemy za przesłanie zdjęcia, otrzymaliśmy je i umieściliśmy na Twoim profilu".
Gratuluje, właśnie wysłałeś request:
typu POST
na URL: instagram.com
z danymi graficznymi, Twoim zdjęciem
i otrzymałeś odpowiedź 201 (utworzono).

Oczywiście, nie miałoby to sensu, gdyby Twoi bliscy nie mogli zobaczyć Twojego nowego, analogowego selfie! Więc Twój najlepszy przyjaciel, zaraz po obudzeniu, sięga po kopertę, adresuje ją:
“Instagram. Menlo Park, California, US”
"Departament Nowych Zdjęć Udostępnionych Przez Moich Przyjaciół"
i wysyła bez żadnej zawartości. Po kolejnych kilku dniach, otrzymuje list zwrotny z kopertą wypełnioną zdjęciami swoich przyjaciół - w tym Twoje selfie!
Przekładając to na komunikację http, Twój przyjaciel wysłał request
typu GET
na URL:  instagram.com/DepartmentNewPicturesSharedByMyFriends
bez żadnej treści 
i w odpowiedzi otrzymał odpowiedź 200 (ok)
oraz dane: zdjęcia swoich przyjaciół.

Tak w dużym uproszczeniu działa komunikacja http, czyli wysyłanie "requestów" i odbieranie "responsów". Jak widzisz dużo łatwiej prowadzić media społecznościowe za pomocą internetu niż tradycyjnej poczty, choć mechanizmy ich działania są bardzo podobne!

Czy mogę sam/sama wysyłać requesty?

Oczywiście! Potrzebujesz do tego "klienta http". To nic innego jak aplikacja która pozwoli Ci ładnie zaadresować Twoją kopertę, włożyć do środka treść a całość wysłać pod wskazany adres. Najprostszym klientem http jest przeglądarka internetowa. Sprawdźmy to!
Potrzebujemy jakiegoś serwisu z którym moglibyśmy prowadzić naszą korespondencję! Na szczęście dobrzy ludzie stworzyli przykładowe usługi które właściwie nie robią nic poza symulowaniem zachowań prawdziwych usług, czyli możemy wysyłać do nich "requesty" i odbierać "responsy" ale nie powoduje to żadnych faktycznych akcji w tych usługach.

Jednym z takich przykładów może być dummyjson.com which simulates an e-commerce service and operates on data in JSON format.

Jeśli wkleisz w pasek przeglądarki https://dummyjson.com/products you will see all the products in our “dummy store”. Congratulations, you have just sent a GET to the URL https://dummyjson.com/products !

Niestety wysyłanie żądań innych niż GET, jest dość kłopotliwe za pomocą przeglądarki, da się to zrobić ale wymaga to odrobiny magii a przecież w pierwszym akapicie napisałem "w prostych słowach"....

Dlatego użyjmy innego klienta http, np: restninja.io - to strona internetowa która pełni rolę klienta http. Tak, taka pokrętna forma incepcji ale działa! Możesz oczywiście wybrać dowolnego innego klienta, np: postman.com, insomnia.rest, httpie.io ale rest ninja wydaje mi się jednym z prostszych.

Inną funkcją udostępnianą przez dummyjson.com jest możliwość dodawania nowych produktów do sklepu. Aby to zrobić należy wysłać POST na URL https://dummyjson.com/products/add z danymi w formacie JSON, które muszą zawierać pole "title". Na poniższym screenie możesz zobaczyć jak wykonać taki request za pomocą rest ninja:

Jako niezwykle spostrzegawczy adept nowej sztuki http-ingu (nie ma takiego słowa, właśnie je wymyśliłem) na pewno zauważyłeś tajemnicze zakładki headers i auth. To tak zwane "meta-dane" requestów. Zawierają wszystkie dodatkowe informacje o naszej komunikacji (o jej bardziej technicznych szczegółach), być może popełnię o nich osobny artykuł, bieżący miał być prosty, więc pozwolę sobie pominąć tą część.

Zachęcam do samodzielnego "poklikania" zarówno w dokumentację dummyjson.com jak i w restninja.io. Miłej zabawy!

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Na górę