Web

Usługi RESTful

Architektura Representational State Transfer i zasady projektowania API.

Wprowadzenie: Od Stron Internetowych do Usług Sieciowych

Na początku rozwoju WWW sieć składała się głównie z dokumentów połączonych hiperłączami i przeznaczonych do odczytu przez ludzi. Przeglądarka wysyłała żądanie, a serwer zwracał dokument HTML, do którego można było dołączyć arkusze CSS i kod JavaScript. Ten model nadal służy do prezentowania treści, natomiast aplikacje korzystają także z wymiany danych między programami.

Nowoczesne aplikacje często składają się z wielu współpracujących części. Mobilna aplikacja bankowa, urządzenie inteligentnego domu i tablica w mediach społecznościowych wymieniają z serwerami dane, aktualizacje oraz polecenia. Taki klient potrzebuje ustrukturyzowanego i przewidywalnego formatu danych, zamiast kompletnego dokumentu HTML. Interakcję między programami za pośrednictwem sieci umożliwia , czyli interfejs programowania aplikacji.

Dla sieciowych API powstały różne style, między innymi SOAP i RPC. W usługach internetowych często stosuje się REST, ponieważ korzysta on z ogólnych mechanizmów HTTP i pozwala opisywać zasoby za pomocą jednolitego interfejsu.

API opisuje dostępne operacje, dane wejściowe i reprezentacje wyników. Reprezentacja może mieć format JSON, XML lub inny typ mediów wskazany w komunikacie.

Czym Jest REST? Styl Architektoniczny i Zestaw Ograniczeń

, czyli Representational State Transfer, jest stylem architektonicznym opisującym sposób projektowania aplikacji sieciowych. Nie jest instalowany ani wdrażany jako pojedynczy protokół. Został opisany przez Roya Fieldinga w rozprawie doktorskiej z 2000 roku. Fielding należał do głównych autorów specyfikacji HTTP, a REST porządkuje zasady architektoniczne zastosowane w sieci WWW.

API lub usługa internetowa zgodna z ograniczeniami REST jest określana jako RESTful. W usługach webowych REST łączy się zwykle z HTTP, identyfikatorami URI do wskazywania zasobów oraz semantyką metod takich jak GET, POST, PUT, PATCH i DELETE. Jednolity interfejs ułatwia klientom rozpoznawanie operacji na zasobach. Sam styl REST nie wymaga HTTP, choć HTTP jest podstawowym protokołem wymiany w sieci WWW.

Sześć Wytycznych Ograniczających REST

API zgodne ze stylem REST spełnia sześć ograniczeń architektonicznych. Wspólnie upraszczają one komunikację, wspierają skalowanie i ułatwiają pracę pośredników sieciowych.

1. Architektura Klient-Serwer
REST rozdziela odpowiedzialności klienta i serwera. Klient obsługuje interfejs użytkownika, a serwer udostępnia zasoby i wykonuje operacje określone przez API. Obie części mogą rozwijać się niezależnie, dlatego serwer można aktualizować bez zmiany klienta, jeśli zachowuje on uzgodniony interfejs.
2. Bezstanowość (Stateless)
Każde żądanie klienta musi zawierać informacje potrzebne do jego zrozumienia i obsługi. Serwer nie przechowuje kontekstu klienta ani stanu sesji między żądaniami. Zasada bezstanowości dopuszcza przechowywanie stanu samych zasobów. Żądania uwierzytelnione zawierają wymagane dane uwierzytelniające przy każdym wywołaniu. Bezstanowość pozwala dowolnemu serwerowi obsłużyć kolejne żądanie i ułatwia skalowanie usługi.
3. Buforowalność (Cacheable)
Odpowiedź musi mieć jawnie albo domyślnie określoną możliwość buforowania. Jeśli można ją buforować, pamięć podręczna może użyć jej ponownie dla równoważnych żądań, zgodnie z czasem świeżości i walidacją. Ogranicza to liczbę żądań kierowanych do serwera. W HTTP zachowanie pamięci podręcznych opisują między innymi dyrektywy nagłówka Cache-Control. Nieaktualna reprezentacja wymaga ponownej walidacji albo zastosowania reguły zezwalającej na użycie danych nieświeżych.
4. Jednolity Interfejs (Uniform Interface)
REST definiuje jednolity interfejs między klientami a serwerami. Obejmuje on cztery ograniczenia szczegółowe: identyfikację zasobów, manipulowanie reprezentacjami, samopisujące się wiadomości oraz hipermedia jako silnik stanu aplikacji. Standaryzacja upraszcza interakcje, choć może ograniczyć optymalizację komunikatów dla pojedynczej aplikacji.
  • Identyfikacja Zasobów: Każdy zasób musi mieć identyfikator URI. W internetowym API identyfikator może być reprezentowany przez ścieżkę, na przykład /uzytkownicy/123 wskazującą użytkownika o ID 123.
  • Manipulacja Zasobami Poprzez Reprezentacje: Klient posługuje się reprezentacją zasobu, zwykle w formacie JSON lub XML. Przy aktualizacji danych użytkownika pobiera reprezentację, modyfikuje ją i wysyła zmienioną reprezentację do serwera.
  • Samopisujące się Wiadomości: Każda wiadomość musi zawierać wystarczająco dużo informacji, aby opisać, jak ją przetworzyć. Osiąga się to za pomocą nagłówków HTTP (np. Content-Type: application/json informuje odbiorcę, że ciało wiadomości jest w formacie JSON) oraz użycia standardowych metod HTTP.
  • Hipermedia jako Silnik Stanu Aplikacji (HATEOAS): Klient powinien móc odkrywać dostępne akcje i zasoby za pomocą hiperłączy zawartych w odpowiedziach serwera. Odpowiedź dotycząca użytkownika może zawierać odnośniki do operacji „edytuj-uzytkownika” i „zobacz-zamowienia-uzytkownika”, wskazując kolejne kroki klienta. W praktyce wiele API wdraża tę zasadę częściowo.
5. System Warstwowy (Layered System)
Klient nie powinien rozpoznawać, czy łączy się bezpośrednio z serwerem końcowym, czy z pośrednikiem. System RESTful może obejmować proxy bezpieczeństwa, serwery buforujące i moduły równoważenia obciążenia. Warstwy można dodawać w celu poprawy wydajności, bezpieczeństwa lub skalowalności, zachowując jednolity interfejs. Każdy pośrednik może jednak zwiększać opóźnienie i narzut przetwarzania.
6. Kod na Żądanie (Code on Demand) (Opcjonalne)
Kod na żądanie jest opcjonalnym ograniczeniem. Serwer może rozszerzyć funkcjonalność klienta przez przesłanie kodu wykonywalnego, takiego jak JavaScript. Przeglądarka internetowa może pobrać taki kod i wykonać go w celu obsługi funkcji aplikacji.

Projektowanie API RESTful: Zasoby i Akcje

Projektowanie API RESTful polega na opisaniu aplikacji za pomocą zasobów i operacji wykonywanych na nich przez metody HTTP. Zasób jest abstrakcją informacji w REST. Może oznaczać dokument, obraz, zbiór innych zasobów lub dowolny obiekt.

Identyfikacja Zasobów

Identyfikacja zasobów zaczyna się od wskazania „rzeczowników” systemu, czyli jego głównych encji. W aplikacji e-commerce zasobami mogą być klienci, produkty, zamówienia i pozycje w koszyku.

Każdy zasób powinien mieć unikalny i spójny adres URI. Przy projektowaniu ścieżek stosuje się następujące zasady:

  • Stosuj rzeczowniki w adresach URL, na przykład /produkty, oraz unikaj nazw operacji takich jak /pobierzProdukty.
  • Używaj rzeczowników w liczbie mnogiej dla kolekcji (np. /zamowienia reprezentuje listę wszystkich zamówień).
  • Używaj unikalnego ID do odwoływania się do konkretnego zasobu w kolekcji (np. /zamowienia/123 odnosi się do konkretnego zamówienia o ID 123).
  • Używaj zagnieżdżonych ścieżek dla powiązanych zasobów (np. /zamowienia/123/pozycje reprezentuje listę pozycji w zamówieniu 123).

Mapowanie Akcji na Metody HTTP

Po zdefiniowaniu identyfikatorów zasobów stosuje się semantykę metod HTTP. Typowy zestaw operacji CRUD obejmuje utworzenie, odczyt, aktualizację i usunięcie danych.

GET służy do pobierania i jest metodą bezpieczną oraz idempotentną. PUT zastępuje reprezentację i jest idempotentny, DELETE także ma tę właściwość, natomiast POST zwykle tworzy zasób albo uruchamia przetwarzanie bez gwarancji idempotencji. PATCH opisuje częściową modyfikację, której szczegóły określa format dokumentu zmian.

Przy równoczesnych aktualizacjach klient może użyć warunków opartych na znaczniku ETag, na przykład nagłówka If-Match. Serwer odrzuca wtedy zapis, gdy reprezentacja jest nieaktualna, co ogranicza ryzyko nadpisania cudzej zmiany.

Kod statusu HTTP przekazuje ogólny wynik operacji. Kody 2xx oznaczają powodzenie, 3xx sygnalizują przekierowanie, 4xx oznaczają błąd po stronie żądania, a 5xx błąd obsługi po stronie serwera. Ciało odpowiedzi może zawierać reprezentację zasobu albo opis problemu w uzgodnionym typie mediów.

OperacjaMetoda HTTPPrzykładowy URLOpis
Odczyt (Kolekcja)GET/produktyPobierz listę wszystkich produktów.
Odczyt (Konkretny element)GET/produkty/456Pobierz szczegóły produktu 456.
UtwórzPOST/produktyUtwórz nowy produkt. Dane nowego produktu są wysyłane w ciele żądania.
Aktualizuj (w całości)PUT/produkty/456Zastąp cały produkt 456 danymi wysłanymi w ciele żądania.
Aktualizuj (częściowo)PATCH/produkty/456Zastosuj częściową aktualizację do produktu 456 (np. zmień tylko cenę).
UsuńDELETE/produkty/456Zażądaj usunięcia produktu 456.

Formaty Danych: "Reprezentacje" w REST

REST jest elastyczny co do formatu używanego do reprezentacji danych. Jednym z najczęściej używanych formatów jest (JavaScript Object Notation). Jego prosta, tekstowa struktura par klucz-wartość i tablic jest łatwa do zrozumienia zarówno dla ludzi, jak i maszyn.

Żądanie GET na adres /produkty/456 może zwrócić następującą reprezentację JSON:

{
"id": 456,
"nazwa": "Bezprzewodowa mysz ergonomiczna",
"cena": 49.99,
"na_stanie": true,
"kategoria": "Peryferia"
}

Aby zaktualizować produkt metodą PUT, klient wysłałby podobny obiekt JSON w ciele żądania. Nagłówek Content-Type opisuje format przesyłanego ciała, a Accept określa akceptowane reprezentacje odpowiedzi, na przykład application/json. API RESTful może także korzystać z XML, YAML lub zwykłego tekstu.

Powiązane artykuły