REST API to jeden z najpopularniejszych stylów architektonicznych, którego znajomość jest niezbędna na rynku pracy backend developerów. W tym artykule pomogę Ci zbudować grunt teoretyczny.
Jeśli nie możesz doczekać się implementacji i praktyki, to zachęcam Cię do przeczytania mojego artkułu Architektura REST API w ramach którego opisuje jak zacząć implementację z wykorzystaniem Spring Boot.
Natomiast jeśli chcesz mieć teorię i praktykę w ramach jednego wideo, to przewiń artykuł na dół – tam znajdziesz zapis z mojego otwartego szkolenia online na temat tworzenia REST API 🙂
Czym jest i jak działa REST API?
Obrazując działanie API można porównać je do pracy kelnera. Jego zadaniem jest dostarczenie tego co zażąda (Request) klient. Jedzenie z kuchni to natomiast dane, które wracają w postaci odpowiedzi (Response).

REST API serwuje dane najczęściej w postaci JSON’a lub XML’a (o czym opowiem Ci później). Najczęściej zasoby pobierane z REST API są wykorzystywane na potrzeby innych aplikacji.
Komunikacja odbywa się poprzez dostęp do zasobu (można porównać go do miejsca w którym stoi restauracja), który jest zdefiniowany w punkcie końcowym. Punkt końcowy jest również bardzo często nazywany endpointem.
Najczęściej adres usługi ma następującą strukturę:
http://<adres-ip-servera>:<port-aplikacji>/<endpoint>
np.:
http://localhost:8080/cars
REST API i protokół HTTP
Jak widzisz dostęp do zasobu odbywa się z wykorzystaniem protokołu HTTP. Należy pamiętać, że REST stanowi jedynie styl architektoniczny i teoretycznie jest on niezależny od protokołu. Jednak jest w praktyce jest on łączony z protokołem HTTP. Więcej na temat tego protokołu i jego wersjach przeczytasz w moim artykule HTTP/3 – wszystko co programista musi o nim wiedzieć.
Podsumowując wraz z wykorzystaniem REST’a wiąże się wykorzystanie tzw. czasowników HTTP. Jest ich kilkanaście, jednak 5 podstawowych, które trzeba znać to:
GET
- Pobiera określony zasobu według podanego identyfikatora.
POST
- Tworzy nowy zasób.
- Jest wykorzystywany do wszystkich innych operacji, które nie wpisują się w ramy innych metod.
- Może służyć do pobierania danych w przypadku kiedy musimy w ramach body dostarczyć dodatkowe parametry.
PUT
- Aktualizuje dany zasób na podstawie podanego identyfikatora.
- Może służyć do tworzenia nowego zasobu jeśli jego identyfikator jest znany.
DELETE
- Usuwa określony zasób według identyfikatora.
PATCH
- Aktualizuje część wskazanego zasobu.
- Od PUT’a różni się tym, że aktualizuje jedynie część zasobu.
Odpowiedź pochodząca z REST API
Formaty danych jakie możemy otrzymywać z REST API to najczęściej:
- JSON – JavaScript Object Notation
- XML – Extensible Markup Language
Z czego najpopularniejszy jest JSON ze względu na lekkość. Dla przykładu JSON:
{ "name":"Przemek", "age":18, "website":"bykowski.pl" }
oraz XML, który dostarcza te same dane:
<person> <name>Przemek</name> <age>30</age> <website>bykowski.pl</website> </person>
Jak widać, odpowiedz w formacie XML ma znacznie większą ilość znaków co przekłada się na większy ruch sieciowy i dłuższy czas transferu danych. Dlatego najpopularniejszym formatem jest lekki JSON. Mile widzianym zwyczajem jest również dostarczanie konsumentowi Twojego API wyboru – jaki format danych ma otrzymać.
Model dojrzałości REST API
Model dojrzałości nazywany również modelem dojrzałości Richardsona opisuje poziomy implementacji REST’a.
LEVEL 0: THE SWAMP OF POX
Udostępniania usługi na wskazanym, jednym adresie, bez podziału na metody HTTP. Klient przekazuje w żądaniu informacje na temat działania jakie chce wykonać.
LEVEL 1: RESOURCES
Dostęp do zasobów odbywa się po konkretnych adresach bez podziału na metody HTTP:
http://localhost:8080/cars/get http://localhost:8080/cars/add http://localhost:8080/cars/update http://localhost:8080/cars/delete
LEVEL 2: HTTP VERBS
Stały adres i czasowniki HTTP
GET http://localhost:8080/cars/ POST http://localhost:8080/cars/ PUT http://localhost:8080/cars/ DELETE http://localhost:8080/cars/
LEVEL 3: HIPEREMIA CONTROLS
Polega to na uwzględnieniu dodatkowej dokumentacji na temat naszego API. Jest to dłuższe zagadnienie, więc na ten temat nagrałem osobne wideo:
Model dojrzałości Richardsona – podsumowanie
Najczęściej większość implementacji REST’a zatrzymuje się na poziomie 2. Jest on wystarczający dla większości przypadków. Poziom trzeci często budzi kontrowersje pomiędzy kosztami implementacji/utrzymania, a potrzebom wykorzystania.
Statusy odpowiedzi
Protokół HTTP dostarcza wiele statusów odpowiedzi, którymi możemy dostarczać klientowi w zależności od przebiegu jego żądania. Jest 5 podstawowych grup:
- 1xx – informacyjne
- 2xx – powodzenie realizacji
- 3xx – przekierowania
- 4xx – błąd po stronie klienta
- 5xx – błąd po stronie serwera
Poniżej dostarczam Ci ściągę, która dostarcza informacje jaki kod powinniśmy zwrócić w zależności od podjętego działania.

6 warunków REST API
Mając już cały przekrój informacji to na podsumowanie dodaje 6 (5) warunków bez których REST nie istnieje. Warto je znać, raczej nie uczyć się na pamięć.
Kiedy nabierzesz praktyki, to wszystkie warunki stają się oczywiste i łatwe do odtworzenia 😉.
- Architektura klient-serwer – klient musi skomunikować się z serwerem aby
uzyskać dostęp do usługi. - Jednolity interfejs – dla realizacji konkretnego działania jest tylko jedna droga dojścia.
- Bezstanowość – bez względu na to jakie wcześniej operacje zostały wykonane, to zawsze każda kolejna operacja nie będzie zmieniała rezultatu dla innej.
- Możliwość zapisywania danych w buforze – wszystkie żądania, które trafiają do REST’a powinny być zapisane w buforze, jeżeli serwer nie jest w stanie obsłużyć na bieżąco wszystkich żądań.
- System warstwowy – jasny podział na warstwy. Użytkownik niekoniecznie musi mieć dostęp bezpośrednio do aplikacji – aplikacja może mieć dodatkową warstwę np. uwierzytelniającą.
- Kod na żądanie – opcjonalny warunek (ale mile widziany). Użytkownik po wykonaniu danego żądania, może otrzymać odpowiedź zwrotną w formie kodu, który następnie może wykorzystać w swojej aplikacji.
Pytanie z rozmowy rekrutacyjnej na temat REST API
Ważną cechą REST’a o której trzeba pamiętać to idempotentność. Ma ona ścisły związek z punktem trzecim opisanym w powyższym akapicie. W najprostszym ujęciu idempotentność jest to ponowienie wykonywania operacji, która nie zmienia rezultatu. Działanie to jest znane głównie z algebry, gdzie przykładem jest wartość bezwzględna:
|x| = x
|-5| = 5
|||-5||| = 5 // wielokrotne wyciąganie wartości bezwzględnej nie wpłynie na zmianę rezultatu.
W kontekście REST API idempotentność oznacza, że dowolna liczba powtarzających się, identycznych żądań pozostawi zasób w tym samym stanie.
Przykład
Wysyłając żądanie o usunięcie zasobu o ID 1, sprawi że ten zasób zostanie usunięty.
curl -X "DELETE" http://localhost:8080/cars/1
Jednak powtarzając dokładnie to samo żądanie, to nic nie zmienimy. Żaden inny zasób nie ucierpi w przypadku, kiedy ponowimy wykonanie żądania. Wyjątkiem jest metoda POST (a w szczególnych przypadkach również PATCH). Ponieważ POST zawsze tworzy nowy zasób.
Warto o tym pamiętać, ponieważ to pytanie również często pojawia się na rozmowie o pracę

Czy PATCH jest idempotentny?
Wszystko zależy od jego implementacji. W większości przypadków jest idempotentny, jednak są przypadki kiedy jego stosowanie może być nieidempotentne i to najlepiej będzie mi to pokazać Ci na uproszczonym przykładzie:
Idempotentny przykład:
// orginal resource { "name":"Przemek", "age":18, } // PATCH request { "name":"Przemek", "age":20, } // resource after request { "name":"Przemek", "age":20, }
nieidempotentny przykład:
// orginal resource { "name":"Przemek", "age":18, } // PATCH request { "name":"Przemek", $increment: 'age' } // resource after request { "name":"Przemek", "age":20, }
Wartość age może być auto inkrementującą się, integralną częścią zasobu. Metoda PUT nadpisałaby tę wartość (ponieważ nadpisuje wszystko), jednak niekoniecznie zadziała to tak w przypadku metody PATCH.
Implementacja REST API w praktyce
Zobacz jak tworze REST API z wykorzystaniem Spring Boot w trakcie jednego z moich otwartych szkoleń online.
Źródła
https://www.restapitutorial.com
https://martinfowler.com/articles/richardsonMaturityModel.html
https://softwareengineering.stackexchange.com
I oczywiście ten temat szerzej poszerzam w swojej książce Spring Boot: LiveBook, dlatego zachęcam Cię do zapoznania się z nią 😉
Dołącz do mojego newstlettera dla początkujących!
Jeśli chcesz otrzymywać ode mnie regularne wiadomości dotyczące implementacji podobnych rozwiązań z wykorzystaniem Spring Boot, to zapisz się:
a ten newsletter już dla doświadczonych Springowców 😊 👇