REST API

Co to jest REST API?

W tym artykule przedstawię podstawowe zasady tworzenia REST API, czyli usług zorientowanych na zasoby (resources). Dowiesz się, co to w ogóle jest REST API, jak tworzyć API w prawidłowy sposób. Co to są poziomy zaawansowania REST API. Jakie metody http stosować, a także czy wersjonować API swoich usług.

 

REST (REpresentational State Transfer) to styl architektury oprogramowania, którego charakterystycznymi cechami są: zorientowanie na zasoby, jednorodny interfejs oraz bezstanowość usług. Styl ten bardzo często jest stosowany w systemach rozproszonych, dzięki czemu przyczynił się do bardzo dynamicznego ich rozwoju w ostatnich latach. Został on zaprezentowany przez Roya Fieldinga roku 2000.

 

Poziomy zaawansowania REST API

Rest nie jest specyfikacją, więc programiści mają pewną dowolność w implementowaniu RESTa. Istnieje jednak całkiem sporo różnego rodzaju reguł, które pomagają wprowadzić dobre praktyki w jego implementacji.

Do sklasyfikowania API restowego możemy posłużyć się modelem dojrzałości Richardsona, który dzieli REST API na 4 różne poziomy.

Poziom 0

API implementujące ten poziom zwykle nie korzysta z wielu adresów URI (jeden URI na cały serwis), nie korzysta z wielu metod http (zwykle wykorzystuje tylko POST), nie korzysta także z HATEOAS (Hypermedia as the Engine of Application State). Mogą to być web serwisy podobne do np. SOAP lub XML-RPC (z tą różnicą, że w SOAP jest dodatkowo koperta, która opakowuje zawartość).

Poziom 1

W pierwszym poziomie usługi zorientowane są na zasób. Wykorzystywane są unikalne adresy URI do rozróżnienia poszczególnych zasobów. W użyciu są zwykle tylko metody GET i POST:

GET http://localhost/orders/1/get
POST http://localhost/orders/create
POST http://localhost/orders/1/update
POST http://localhost/orders/1/delete

Poziom 2

W poziomie tym używane są dodatkowe metody http: GET, POST, PUT, PATCH, DELETE. Metody te powinny być używane zgodnie ze swoim przeznaczeniem. Poza tym API powinno korzystać z odpowiednich statusów http.

GET http://localhost/orders/1
POST http://localhost/orders
PUT http://localhost/orders/1
DELETE http://localhost/orders/1

Poziom 3

Poziom 3 zakłada obsługę HATEOAS (Hypermedia as the Engine of Application State). Dzięki czemu w odpowiedzi wysyłane są dodatkowe linki pozwalające poruszać się po API. Dzięki temu klient API ma ułatwione zadanie i „wie”, gdzie może pobrać dodatkowe informacje. Użycie HATEOAS pozwala zminimalizować dokumentację API.

Im wyższy poziom został zaimplementowany, tym nasze API jest bardziej zgodne z architekturą REST.

Który poziom zaimplementować?

Zwykle, gdy mówimy o „prawdziwych” RESTach, to w grę wchodzą poziomy 2 i 3. A najczęściej implementowany jest poziom 2 z tego względu, że często można obejść się bez zastosowania HATEOASa. Niektórzy też twierdzą, że HATEOAS powoduje dodatkowy poziom komplikacji i nie daje aż tak wiele w zamian. No i bez niego implementowanie API jest trochę szybsze.

Więcej możesz przeczytać w artykule Martina Fowlera Richardson Maturity Model.

 

Jak poprawnie tworzyć REST API?

Zacznijmy od odpowiedniego nazewnictwa w URI. Używamy rzeczowników w liczbie mnogiej np: /orders, /users, /customers. Adres zasobu musi być przygotowany w odpowiedni sposób :

resource1/{resource-id}/resource2/{resource-id}/resource3/{resource-id} itd.

Jeśli chcesz pobrać wszystkie zamówienia klienta, to URI będzie wyglądało tak: /customers/1/orders (gdzie 1-to id klienta). Jeżeli chcesz pobrać konkretne zamówienie, to: /customers/1/orders/1.

Używaj odpowiednich metod http

Odpowiednie metody http w połączeniu z odpowiednim nazewnictwem w URI daje nam spójną całość w postaci dobrze zdefiniowanych endpointów restowych:

GET /customers – zwraca listę obiektów

GET /customers/1 – zwraca pojedynczy obiekt

POST /customers – tworzy nowy zasób

PUT /customers/1 – aktualizuje dany zasób

DELETE /customers/1 – usuwa zasób

Podobnie dla bardziej rozbudowanych zasobów

GET /customers/1/orders – zwraca listę obiektów

GET /customers/1/orders/1 – zwraca pojedynczy obiekt

POST /customers/1/orders – tworzy nowy zasób

PUT /customers/1/orders/1 – aktualizuje dany zasób

DELETE /customers/1/orders/1 – usuwa zasób

Jakie statusy http stosować?

Najczęściej używanym statusem jest chyba status 200 OK. Ale to nie znaczy, że trzeba go stosować wszędzie. W przypadku zapytań POST można stosować status 201 Created lub 202 Accepted, jeśli zapytanie jest asynchroniczne.

Trzeba pamiętać o tym, żeby nie zwracać zawsze tego samego statusu do różnych sytuacji. Np.  w Springu domyślny status błędu to 500 Internal Server Error. Nie ważne czy sterownik bazy danych rzuci jakiś wyjątek, czy zostanie zwrócony błąd walidacji, to Spring zawsze zwróci status 500. Jest to bardzo niepoprawne, ponieważ są to dwie różne klasy problemów. W pierwszym wypadku np. aplikacja nie może się połączyć z bazą danych i nie funkcjonuje poprawnie. W drugim wszystko działa tak jak trzeba, tylko użytkownik wprowadził złe dane do aplikacji.

W drugim przypadku lepiej jest zwracać status 400 BAD REQUEST.

Poniżej lista różnych typów statusów:

1×× informacyjne
2×× sukcesu
3×× przekierowania
4×× błędy klienta
5×× błędy serwera

Spis wszystkich statusów http znajdziesz tutaj

Odpowiednio przygotowane odpowiedzi błędów

Dobrze jest, żeby odpowiedź z błędem zawierała jakieś pole, które opisuje ten błąd np. message. Nie jest to jednak w żaden sposób narzucone. Najlepiej jest zwracać znaczące komunikaty błędów, ale nie zawsze jest to pożądane. Czasem z różnych względów będziesz musiał zwracać generyczny komunikat „Wystąpił błąd, skontaktuje się z administratorem aplikacji” lub coś podobnego.

Domyślna odpowiedź w Spring Framework wygląda tak jak poniżej i zwykle jest ona wystarczająca, żeby dowiedzieć się co się stało w danej sytuacji:

{
    "timestamp": "2020-02-17T09:30:00.111+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "Error processing the request!",
    "path": "/customers"
}

Jak dodawać dodatkowe parametry?

Czasem jest potrzeba skorzystania z dodatkowych parametrów w aplikacji. Np. w sytuacji, gdy potrzebujemy stronicowania wyników. Wtedy najlepiej dodać odpowiedni parametr jako część query stringa w taki oto sposób: ?page=1.

Podobnie możesz zrobić z parametrami opcjonalnymi np: ?sort=id_asc lub połączyć je razem ?page=1&sort=id_asc.

Dodawanie parametrów opcjonalnych w ścieżce (URI) jest mało wygodne i może prowadzić do nieporozumień dlatego wygodniej jest dodawać je jako część query stringa.

Jak wykonywać akcje korzystając z REST API?

To chyba jedno z częściej pojawiających się pytań dotyczących REST API. I jeśli chcemy być zgodni z zaleceniami RESTa, to właściwie nie powinniśmy myśleć o akcjach, tylko o stanie, który te akcje powodują lub zmieniają (ST w REST to state transfer).

Załóżmy, że nasza akcja to stworzenie jakiegoś backupu. Stan backupu po wykonaniu akcji to „utworzony”, więc możemy posłużyć się tu po prostu statusem i wysłać następujące żądanie.

POST http://localhost/backups
{"status":"created"} //payload

Zawsze po wywołaniu takiego endpointa stworzymy nowy backup.

Można też skorzystać z innego sposobu, chyba trochę mniej zgodnego z czystym RESTem, czyli użycie w URI akcji jako parametru.

POST http://localhost/backups/create

Czasem sztywne trzymanie się wytycznych RESTa wprowadza zamęt zamiast pomagać. I warto poszukać najprostszego rozwiązania.

Czy wersjonować REST API?

Kolejny ważny problem REST API to ciągle powracające pytanie, czy powinniśmy je wersjonować, albo kiedy zacząć je wersjonować. Z moich doświadczeń wynika, że lepiej tego nie robić. Jeśli tego nie potrzebujesz, a zwykle tak jest, to po prostu tego nie rób. A dlaczego? Ponieważ jest to dosyć skomplikowane w utrzymaniu i bez względu na to jaką metodę wersjonowania zastosujesz to i tak będzie to trudne.

Jeśli już musisz wersjonować API, to chyba najlepszym sposobem jest dodanie odpowiedniego nagłówka http z numerem wersji. Pamiętać trzeba przy tym, że endpoint bez podania wersji powinien udostępniać API w wersji pierwszej (bazowej) inaczej może prowadzić to do nieporozumień.

Accept: application/vnd.example.v1+json

 

Podsumowanie

Coraz więcej aplikacji korzysta z REST API. Jest to bardzo wygodny sposób tworzenia API i każdy developer powinien cokolwiek o nim wiedzieć. Często też na rozmowach rekrutacyjnych można spotkać się z pytaniami dotyczącymi RESTa np. „Jakiej metody http powinniśmy użyć do stworzenia nowego zasobu, a jakiej do aktualizacji?”.

Cały artykuł powstał w oparciu o podręcznik tworzenia API od Google, który znajdziesz poniżej w źródłach.30

 

O tworzeniu Rest Api także mówię w trzeciej części mojego kursie Spring Boota na Youtubie.

Kurs Spring Boot – Jak tworzyć Rest Api?

 

Źródła:

https://cloud.google.com/apis/design

https://martinfowler.com/articles/richardsonMaturityModel.html

https://httpstatuses.com

 

Mateusz Dąbrowski

Cześć jestem Mateusz, zajmuję się programowaniem już ponad 12 lat z czego ponad 8 programuję w Javie. Zapraszam Cię do lektury mojego bloga. Możesz przeczytać więcej o mnie >>TUTAJ<<

5 thoughts to “Co to jest REST API?”

  1. Cześć.

    Myślę, że warto było by wspomnieć o mniej popularnych metodach HTTP, mianowicie HEAD i OPTIONS. Pojawiają się one również na rozmowach rekrutacyjnych.

    Pozdrawiam,
    Damian

    1. Dzięki Damian za komentarz. W tzw. międzyczasie postaram się dopisać coś o tych metodach 😉

  2. Dodałbym, może trochę nie w temacie, taką uwagę – niech zaimplementowany REST zwraca sensowny, łatwo identyfikowalny zasób. Niech to nie będą to wymieszane pola kilku obiektów, z którego dopiero Twój klient ma skleić jakiś sensowny twór.
    To taka uwaga na marginesie po moich ostatnich doświadczeniach z zewnętrznym, restowym api, którego konsumentem jest pisana przez mój zespół aplikacja. Najwyraźniej zwracanie częściowych danych osobowych pomieszanych z adresem i przeplecionych konfiguracją konta googla to nowa meta niektórych 'programistów’.

  3. Cześć, super forum, pomogło mi w stworzeniu swojego API, dzięki za Twoją prace.

    Mam teraz pytanie, chciałbym umieścić swoje API na zewnętrznym serwerze, dodam, że jest to api dla aplikacji mobilnej za pomocą której użytkownicy bedą wprowadzać swoje dane osobowe (imie, nazwisko numer telefonu), zatem zależy mi na bezpieczeństwie tych danych.
    Czy poleciłbyś jakiś hosting w którym mógłbym wystawiać swoje API + komunikacji z bazą postgresql. Czy są jakieś gotowe rozwiązania, tak żebym nie musiał się martwić z konfiguracją i zabezpieczeniem serwera VPS ?

    1. W zasadzie każdy VPS na początek będzie tak samo dobry. Jeśli nie wiesz, jakie masz albo jakie powinieneś mieć wymagania co do VPSa, to proponuję znaleźć najtańszy, tak żeby niepotrzebnie nie przepłacać. Co do bezpieczeństwa, to nie wiem, co dokładnie robisz, więc ciężko powiedzieć coś więcej. Poczytaj o najczęstszych typach ataków na aplikacje np. Sql Injection itp.

Komentarze są zamknięte.