Co to jest usługa REST? Richardson maturity model oraz poziomy 0,1,2.

Martin Fowler, kilka lat temu pisał o tzw. Richardson maturity model, którego autorem jest tak naprawdę Leonard Richardson. Groźnie brzmiąca nazwa, jak zwykle nie opisuje nic bardzo skomplikowanego. Nie mniej jednak, model ten doskonale opisuje założenia usług RESTful. W zasadzie nie ma framework’ów, które wymuszałyby poprawną implementację REST, stąd niezbędne jest zrozumienie jakie są założenia tych usług. Programiści zbyt często luźno interpretują pojęcie REST. Moim zdaniem, w momencie, gdy REST wchodził, nie było jasnej definicji wymagań i założeń.

Model jest podzielony na cztery poziomy (Level 0, Level 1, Level 2, Level 3). Jeśli zaimplementujemy wszystkie z nich, wtedy możemy mówić, że w pełni implementujemy model. Nie znaczy to jednak, że nasza usługa będzie automatycznie REST, ponieważ jest to dużo bardziej złożone niż przedstawiany tutaj model. Moim zdaniem są to po prostu fundamenty usługi. Nie znaczy to również, że bez poziomu trzeciego, nasza usługa jest zła – wszystko zależy od wymagań.

Poziom 0

Zacznijmy od zerowego poziomu. Mówi on po prostu to, że usługa REST to nie nowy protokół, a całość komunikacji jest już oparta na istniejącym protokole. Najczęściej jest to po prostu tunelowanie HTTP, czyli wykorzystanie HTTP z odpowiednim nagłówkiem i ciałem. Przykładowo, aby dodać nowego klienta do bazy, możemy wysłać:

POST /customerService HTTP/1.1 <AddCustomer FirstName="Piotr" LastName="Zielinski"/>

Jako odpowiedź dostaniemy wtedy HTTP 200. Na poziomie zerowym, będzie zawsze to 200. W przypadku niepowodzenia operacji, po prostu błąd będzie dołączony jako opis (np. w formancie  XML), ale status zawsze będzie 200.

Jeśli chcemy zwrócić informacje o konkretnym kliencie, również wysyłamy zapytanie za pomocą HTTP:

POST /customerService HTTP/1.1 <GetCustomer id=1/>

Odpowiedź:

HTTP/1.1 200 OK <Customer FirstName="Piotr" LastName="Zielinski"/>

Jak widzimy, HTTP służy nam do komunikacji. W ciele wstawiamy nasze zapytanie. Nie jest to nic innego jak RPC, czyli zdalne wywoływanie procedur. Można to porównać do klasycznych usług, gdzie wywołujemy po prostu konkretne metody na danej usłudze.

Poziom 1

Poziom pierwszy wprowadza definicje zasobów. Nie będziemy już wysyłać zapytań do jednego punktu, ale usługa będzie tworzyć hierarchie zasobów. Innymi słowy, aby zwrócić dane klienta, wystarczy:

POST /customerServices/customers/1 HTTP/1.1 <GetCustomer/>

Proszę zwrócić uwagę na adres. Dane uzyskujemy wysyłając zapytanie do konkretnego adresu, a nie głównego, jak to było  w warstwie zerowej. Innymi słowy, aby np. zwrócić numer telefonu klienta o identyfikatorze 1, wysyłamy:

POST /customerServices/customers/1/phone HTTP/1.1 <GetPhoneNumber/>

W przypadku poziomu zerowego, byłoby to:

POST /customerServices HTTP/1.1 <GetCustomerPhone id="1"/>

Kluczami do zrozumienia poziomu 1, są słowa “hierarchia” oraz “zasoby”. Nie odwołujemy się do głównego adresu, ale konkretne zapytania tworzą po prostu drzewo zasobów.

Poziom 2

Proszę zauważyć, że wszystkie powyższe zapytania korzystały wyłącznie z HTTP Post. Poziom drugi rozpoznaje typ zapytania, tzn. POST, PUT, GET, DELETE. W celu zwrócenia danych konkretnego klienta wystarczy:

GET /customerServices/customers/1 HTTP/1.1

GET służy zatem do zwracania danych i nie trzeba już tego określać w HTTP body za pomocą nazwy komendy, jak to było w poprzednich warstwach. HTTP PUT zwykle służy do aktualizacji danych, POST do wstawiania nowych wierszy, a DELETE naturalnie do ich usuwania.

Ponadto jest różnica w jaki sposób zwracamy odpowiedź. W poprzednich warstwach było to po prostu HTTP 200 OK plus ewentualnie jakiś opis. Teraz chcemy dostarczyć bardziej dokładną odpowiedź. Na przykład, po dodaniu klienta dostaniemy:

HTTP/1.1 201 Created Location: /customers/1

Jak widać, operujemy tutaj na statusie HTTP i nie zwracamy tylko 200, a np. 201, gdy nowy zasób został dodany. Ponadto dobrze zwrócić również lokalizacje właśnie dodanego zasobu (Location). Zamiast zwracania treści błędu, jak to miało miejsce na poziomach 01,2, zwracamy konkretny status HTTP, który ma już dobrze znaną definicję ze standardów webowych.

Do opisania pozostał jeszcze poziom 3, ale tym zajmiemy się w kolejnym poście bo jest on nieco bardziej skomplikowany.

Z dzisiejszego postu powinno jasno wynikać, że usługi REST to kompletnie inna idea niż usługi SOAP i klasyczny RPC. Tutaj nie chodzi po prostu o wywołanie jakieś metody na usłudze.

Podsumowując:

1. Poziom  0 – REST powinien być oparty na istniejącym protokole np. HTTP.

2. Poziom 1 – Zasoby oraz ich hierarchia.

3. Poziom 2 – HTTP verbs oraz HTTP status codes.

2 thoughts on “Co to jest usługa REST? Richardson maturity model oraz poziomy 0,1,2.”

Leave a Reply

Your email address will not be published.