RESTful API – jak zrobić je dobrze?

RESTful API – każdy mniej-więcej wie co to jest. Wiemy, że chodzi o HTTP, o różne metody tego protokołu. Przeważnie wiemy, że warto używać JSONa. Niestety często na tym wiedza większości programistów się kończy. Skąd więc możemy wiedzieć, że tworzymy dobre API RESTowe?

Szczęśliwie mamy model dojrzałości serwisów restowych (Richardson Maturity Model). RMM jest dla nas przewodnikiem po tym jak dobrze zrobić REST. Składa się z kilku pojęć. Im więcej z nich zaimplementujemy tym bardziej RESTowy serwis zrobimy.

Zasoby

Pierwsza i najważniejsza własność RESTa – zasoby. Każdy zasób ma swój adres. Adres jest unikalny i zawsze ten sam. Nie może być dwóch zasobów pod tym samym adresem. Jeden zasób nie powinien też pojawiać się pod kilkoma adresami. Dobre przykłady:

http://mój.blog/rest/artykul_pierwszy/
https://moje.api/rest/user/adam

Złe przykłady – gdy pod tym samym adresem może być kilka różnych zasobów:

http://moje.api/last_item/

Albo jeszcze gorzej, gdy ten sam zasób może mieć kilka adresów

http://moje.api/user/adam?format=xml
http://moje.api/user/adam?format=json

Korzystamy z całego HTTP

Wprawdzie REST nie wymusza użycia HTTP, ale prawie zawsze idzie z nim w parze. HTTP to coś więcej niż znane wszystkim GET i POST. Mamy nagłówki żądania i odpowiedzi, mamy kody odpowiedzi, mamy też kilka różnych metod wywołania. REST stara się wykorzystać wszystkie te możliwości do maksimum.

W poprzednim przykładzie błędem byłoby żądanie (GET) formatu danych w adresie:

http://moje.api/user/adam?format=json

Jeśli chcemy dobrze RESTować to adres zasobu się nie zmienia niezależnie od formatu. Różne formaty uzyskujemy wysyłając jako klient nagłówki, np:

Accept: application/json, text/xml

W ten sposób API wie w jakim formacie odesłać dane. Jeśli nie potrafi obsłużyć żadnego z żądanych formatów powinno odpowiedzieć kodem błędu:

415 Unsupported Media Type

Obie strony wiedzą jak się komunikować. Klient może reagować na błędy a niektóre z nich wręcz próbować poprawiać samemu.

W podobny sposób korzystamy z metod HTTP. Np. POST tworzy nowy zasób, PUT zapisuje jego treść, PATCH modyfikuje zawartość, DELETE kasuje a OPTIONS informuje o tym, co możemy zrobić z zasobem.

Semantyczna komunikacja

Pod tym enigmatycznym tytułem kryje się prosta zasada:

Lepiej, gdy dane same się opisują niż gdyby musiała je opisywać dokumentacja.

Przyjrzyjmy się dwóm przykładom tych samych danych. API zwraca nam listę elementów w XML:

<results>
 <elem id="1">Nasz element listy</elem>
 <elem id="2">Nasz drugi element listy</elem>
</results>

Dzięki takim danym znamy identyfikator elementu oraz tekst, który może jest jego nazwą, może skróconym opisem. Co zrobić, gdy chcemy dowiedzieć się więcej o elemencie? Zaglądamy do dokumentacji, która pewnie powie nam, że pod adresem http://nasze.api/elem/<id> znajduje się nasz element (zasób), gdzie <id> to identyfikator elementu.

Czy nie można było od razu? Można, wykorzystując semantyczny opis danych:

<results>
   <elem id="1">
      <name>Nasz element listy</name>
      <link href="http://nasze.api/elem/1" />
   </elem>
   <elem id="2">
      <name>Nasz drugi element listy</name>
      <link href="http://nasze.api/elem/2" />
   </elem>
</results>

Co w ten sposób zyskaliśmy? Lista korzyści będzie długa:

  1. Od razu wiadomo gdzie szukać informacji o elemencie (link).
  2. Wiemy, że tekst jest w rzeczywistości jego nazwą.
  3. Możemy w przyszłości przenieść bazę elementów pod inny adres. Po stronie API tylko zmienimy linki. Wszystkie aplikacje korzystające z naszego API będą nadal działać.
  4. Adres zasobu już nie zależy od jego identyfikatora. Jeśli zechcemy ukryć informację ile jest elementów (np. zamówień) w systemie – porzucimy identyfikatory na rzecz kodów.
  5. Jeśli nie chcemy dawać klientowi dodatkowych informacji o elementach a jedynie listę – chowamy linki i po problemie. Klient nie wie gdzie szukać szczegółów elementów.
  6. W dokumentacji nie musimy nawet pisać adresu zasobów.
  7. Programista korzystający z naszego API rzadziej sięga do dokumentacji, przez to szybciej tworzy swoją aplikację. :)

W praktyce semantyczna komunikacja w REST jest określana sktórem HATEOAS (Hypertext As The Engine Of Application State). Pod tym dziwnym skrótem kryje się idea, aby dane zapisywać z maksymalną możliwą informacją o ich znaczeniu. Idealny serwis może posiadać tylko jeden adres główny. Adresy wszystkich pozostałych zasobów klient zdobywa poprzez semantyczne linki.

Na koniec

Tym krótkim opisem chciałem rozwiać wątpliwości o co tak naprawdę chodzi w REST. To nie tylko modne słowo i łatwa technika tworzenia serwisów. REST to filozofia tworzenia aplikacji, która już zagościła w naszej rzeczywistości. Jest częścią dawno zapowiadanej Semantycznej Sieci (Semantic WEB zwanej też Web 3.0). O Semantycznej Sieci będę jeszcze pisał.

Warto poczytać

The RESTful cookbook [en] – doskonały serwis poświąceony REST.

Dodaj komentarz

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