Wiele z tego, co wydawało mi się, że wiem o REST, jest najwyraźniej błędne - i nie jestem sam. To pytanie ma długie wprowadzenie, ale wydaje się być konieczne, ponieważ informacje są nieco rozproszone. Właściwe pytanie kończy się, jeśli znasz już ten temat.
Od pierwszego akapitu interfejsów API REST Roya Fieldinga muszą być oparte na hipertekstach , jest całkiem jasne, że uważa, że jego praca jest szeroko błędnie interpretowana:
Irytuje mnie liczba osób nazywających dowolny interfejs oparty na HTTP jako REST API. Dzisiejszym przykładem jest SocialSite REST API . To jest RPC. Krzyczy RPC. Na wyświetlaczu jest tak wiele sprzężeń, że należy mu przyznać ocenę X.
Następnie Fielding wymienia kilka atrybutów interfejsu API REST. Niektóre z nich wydają się być sprzeczne zarówno z powszechną praktyką, jak i popularnymi radami na SO i innych forach. Na przykład:
REST API należy wprowadzić bez wcześniejszej wiedzy poza początkowym identyfikatorem URI (zakładką) i zestawem standardowych typów mediów, które są odpowiednie dla zamierzonej grupy odbiorców (tj. Mają być zrozumiane przez każdego klienta, który może korzystać z API). ...
REST API nie może definiować stałych nazw zasobów ani hierarchii (oczywiste połączenie klienta i serwera). ...
REST API powinien poświęcić prawie cały swój opisowy wysiłek na zdefiniowanie typu (-ów) mediów używanych do reprezentowania zasobów i sterowania stanem aplikacji lub na definiowanie rozszerzonych nazw relacji i / lub znaczników z obsługą hipertekstu dla istniejących standardowych typów mediów. ...
Idea „hipertekstu” odgrywa kluczową rolę - znacznie bardziej niż struktura URI czy znaczenie czasowników HTTP. „Hipertekst” jest zdefiniowany w jednym z komentarzy:
Kiedy [Fielding] mówię hipertekst, mam na myśli równoczesną prezentację informacji i sterowanie w taki sposób, że informacja staje się afordancją, przez którą użytkownik (lub automat) uzyskuje wybory i wybiera działania. Hypermedia to tylko rozwinięcie tego, co tekst oznacza włączenie czasowych kotwic do strumienia mediów; większość badaczy zrezygnowała z tego rozróżnienia.
W przeglądarce hipertekst nie musi być kodem HTML. Maszyny mogą podążać za linkami, jeśli rozumieją format danych i typy relacji.
Zgaduję w tym miejscu, ale pierwsze dwa punkty powyżej wydają się sugerować, że dokumentacja API dla zasobu Foo, która wygląda jak poniżej, prowadzi do ścisłego sprzężenia między klientem a serwerem i nie ma miejsca w systemie RESTful.
GET /foos/{id} # read a Foo
POST /foos/{id} # create a Foo
PUT /foos/{id} # update a Foo
Zamiast tego agent powinien zostać zmuszony do znalezienia identyfikatorów URI dla wszystkich Foos, na przykład przez wysłanie żądania GET przeciwko / foos. (Te identyfikatory URI mogą być zgodne z powyższym wzorcem, ale to nie ma znaczenia). Odpowiedź wykorzystuje typ mediów, który jest w stanie przekazać, jak uzyskać dostęp do każdego elementu i co można z nim zrobić, co prowadzi do trzeciego punktu powyżej. . Z tego powodu dokumentacja API powinna koncentrować się na wyjaśnieniu sposobu interpretacji hipertekstu zawartego w odpowiedzi.
Ponadto za każdym razem, gdy żądany jest identyfikator URI do zasobu Foo, odpowiedź zawiera wszystkie informacje potrzebne agentowi do odkrycia, jak postępować, na przykład, uzyskując dostęp do powiązanych i nadrzędnych zasobów za pośrednictwem ich identyfikatorów URI lub podejmując działania po utworzeniu / usunięcie zasobu.
Kluczem do całego systemu jest to, że odpowiedź składa się z hipertekstu zawartego w typie nośnika, który sam przekazuje agentowi opcje postępowania. Nie różni się to od sposobu, w jaki przeglądarka działa dla ludzi.
Ale to tylko moje przypuszczenie w tym konkretnym momencie.
Fielding opublikował dalszy ciąg , w którym odpowiedział na krytykę, że jego dyskusja była zbyt abstrakcyjna, pozbawiona przykładów i bogata w żargon:
Inni będą próbowali rozszyfrować to, co napisałem, w sposób bardziej bezpośredni lub mający zastosowanie do niektórych praktycznych problemów dnia dzisiejszego. Pewnie nie, bo jestem zbyt zajęty zmaganiem się z kolejnym tematem, przygotowywaniem się do konferencji, pisaniem innego standardu, podróżowaniem w jakieś odległe miejsce lub po prostu robieniem drobiazgów, które pozwalają mi poczuć, że zarobiłem na wypłatę.
A więc dwa proste pytania do ekspertów REST z praktycznym nastawieniem: jak interpretujesz to, co mówi Fielding i jak wprowadzasz to w życie podczas dokumentowania / wdrażania interfejsów API REST?
Edycja: to pytanie jest przykładem tego, jak trudno jest się czegoś nauczyć, jeśli nie masz nazwy dla tego, o czym mówisz. W tym przypadku nazwa to „Hypermedia jako silnik stanu aplikacji” (HATEOAS).
Odpowiedzi:
Myślę, że twoje wyjaśnienie w większości to obejmuje. Identyfikatory URI to nieprzezroczyste identyfikatory, które w większości nie powinny być przekazywane poza identyfikator URI zakładki używany przez klienta użytkownika w celu uzyskania dostępu do aplikacji.
Jeśli chodzi o dokumentację, to pytanie zostało omówione kilka razy. Dokumentujesz swój typ multimediów wraz z zawartymi w nim kontrolkami hiperłącza (linkami i formularzami) oraz modelem interakcji, jeśli chcesz (zobacz AtomPub).
Jeśli dokumentujesz identyfikatory URI lub jak je zbudować, robisz to źle.
źródło
Twoja interpretacja wydaje mi się poprawna. Wierzę, że ograniczenia Fieldinga można praktycznie zastosować.
Naprawdę chciałbym, aby ktoś opublikował kilka dobrych przykładów dokumentowania interfejsu REST. Jest tak wiele kiepskich przykładów, że kilka ważnych, na które można wskazać użytkownikom, byłoby bardzo cenne.
źródło
application/json
i że model zasobów to naprawdę relacje. Czy źle zrozumiałem ten aspekt REST? Przeczytałem również jedną z twoich odpowiedzi SO, która wydaje się wskazywać, że tych kontraktów „jednego atrybutu” należy unikać ...Szukałem dobrego przykładu interfejsu API napisanego zgodnie z HATEOAS i miałem problem ze znalezieniem takiego (stwierdziłem, że zarówno API SunCloud, jak i AtomPub są trudne do zastosowania w „normalnej” sytuacji API). Spróbowałem więc zrobić realistyczny przykład na moim blogu, postępując zgodnie z radami Roya Fieldingsa, co to znaczy być właściwą implementacją REST. Znalezienie tego przykładu było dla mnie bardzo trudne, mimo że jest on w zasadzie dość prosty (po prostu mylący podczas pracy z interfejsem API w przeciwieństwie do strony internetowej). Rozumiem, z czym Roy się nie zgadzał, i zgadzam się, że to tylko zmiana sposobu myślenia, aby poprawnie zaimplementować interfejs API.
Spójrz: Przykład API przy użyciu Rest
źródło
Jedynym wyjątkiem od udzielania instrukcji, jak budować URI, jest to, że dopuszczalne jest przesłanie szablonu URI w odpowiedzi hipertekstowej, z polami, które mają być automatycznie podstawione przez klienta, przy użyciu innych pól w hipertekście. Zwykle nie oszczędza to jednak dużej przepustowości, ponieważ kompresja gzip radzi sobie z powtarzającymi się częściami identyfikatorów URI na tyle dobrze, aby nie zawracać sobie tym głowy.
Kilka dobrych dyskusji na temat REST i związanych z nim HATEOAS:
Zalety (również) używania HATEOAS w interfejsach API RESTFul
JAK OTRZYMAĆ KAWĘ
źródło
Dla zainteresowanych znalazłem szczegółowy przykład HATEOAS w praktyce w Sun Cloud API .
źródło
Większość ludzi popełnia błąd polega na tym, że (przynajmniej tak mi się wydaje) w świecie REST nie dokumentuje się swojego „interfejsu odpoczynku”, co dokumentuje się jako typ nośnika, niezależnie od serwera lub usługi.
źródło
Myślę, że przez tyle lat, kiedy REST istnieje, technolodzy pogodzili się z koncepcją zasobu i tym, co naprawdę jest, a co nie jest RESTful.
Zgodnie z modelem dojrzałości Richardsona istnieją 4 poziomy (0-3), które definiują, jak REST -owy jest Twój interfejs API, przy czym 3 oznaczają prawdziwie RESTful API, tak jak chciał tego Roy Fielding.
Poziom 0 jest wtedy, gdy masz jeden identyfikator URI punktu wejścia - taki jak SOAP.
Poziom 1 oznacza, że API jest w stanie rozróżnić różne zasoby i ma więcej niż jeden punkt wejścia - nadal pachnie SOAP.
Poziom 2 dotyczy czasowników HTTP - głównie GET, POST, DELETE. To jest poziom, na którym naprawdę pojawia się REST.
Na poziomie 3 zaczynasz używać elementów sterujących hipermedii, aby uczynić swoje API prawdziwie REST
Sugerowane linki do dalszego czytania:
źródło
Absolutnie poprawne. Zwróciłbym ponadto uwagę, że szablony URI doskonale sprawdzają się w aplikacji zgodnej z REST, o ile wzorce pochodzą z dokumentów otrzymanych z serwera (odpowiednim przykładem jest OpenSearch). W przypadku szablonów URI dokumentujesz, gdzie są używane i jakie są oczekiwane symbole zastępcze w szablonie, ale nie same szablony. Nieco w przeciwieństwie do tego, co powiedział Wahnfrieden, nie jest to wyjątek.
Na przykład w mojej pracy mamy wewnętrzny system zarządzania domenami, a dokument serwisowy określa dwa szablony URI: jeden do tworzenia najlepszego zgadywanego URI dla zasobu domeny, a drugi do tworzenia identyfikatora URI do sprawdzania dostępności domeny. Nadal można przejrzeć kolekcję domen, aby dowiedzieć się, jaki jest identyfikator URI danej domeny, ale biorąc pod uwagę ogromną liczbę domen, którymi zarządza, nie byłoby to wykonalne dla klienta, więc dałoby mu możliwość odgadnięcia, co Identyfikator URI zasobu domeny może być olbrzymią korzyścią pod względem łatwości implementacji z punktu widzenia klienta i przepustowości z punktu widzenia serwera.
Wracając do pytania: nasza dokumentacja normatywna przedstawia zasoby, wpływ różnych metod na te zasoby oraz używane typy nośników reprezentacji i ich schematy, a także rodzaje zasobów, na które wskazują identyfikatory URI w tych reprezentacjach.
Dołączamy również dokumentację nienormatywną (informacyjną), do której dołączono zastrzeżenie, aby nie wczytywać zbyt wiele w identyfikatory URI wspomniane w dokumencie, co zawiera przykłady typowych interakcji klient-serwer. W ten sposób dość abstrakcyjna dokumentacja normatywna jest konkretna.
źródło
Załóżmy, że
GET /foos/createForm
jest wywoływany, aby uzyskać wartości pól formularza, dla których należy podać, kiedy przechodzimy do tworzeniaPOST /foos
. Teraz ten konkretny adres URL, tj. 1 używany do tworzenia foos, powinien być wymieniony w odpowiedziGET /foos/createForm
jako link do akcji przesyłania zgodnie z propozycją Fieldinga, prawda?W takim razie jaka jest korzyść z mapowania akcji na dobrze znane czasowniki HTTP na akcje, rzecz „konwencja przez kod / konfigurację” zostaje anulowana.
źródło