Dlaczego małe stałe słownictwo jest postrzegane jako zaleta usług RESTful?

13

Tak więc usługa RESTful ma ustalony zestaw czasowników w swoim słowniku. Usługa sieci Web RESTful pobiera je z metod HTTP. Zdefiniowanie stałego słownictwa ma pewne zalety, ale tak naprawdę nie rozumiem o co chodzi. Może ktoś może to wyjaśnić.

Dlaczego ustalone słownictwo określone przez REST jest lepsze niż dynamiczne definiowanie słownictwa dla każdego stanu? Na przykład programowanie obiektowe jest popularnym paradygmatem. RPC zostało opisane w celu zdefiniowania stałych interfejsów, ale nie wiem, dlaczego ludzie zakładają, że RPC jest ograniczony przez te ograniczenia. Możemy dynamicznie określić interfejs tak, jak usługa RESTful dynamicznie opisuje jego strukturę treści.

REST ma być korzystny, ponieważ może się rozwijać bez rozszerzania słownictwa. Usługi RESTful rozwijają się dynamicznie, dodając więcej zasobów. Co jest takiego złego w rozszerzaniu usługi poprzez dynamiczne określanie słownictwa dla poszczególnych obiektów? Dlaczego po prostu nie używamy metod, które są zdefiniowane na naszych obiektach jako słownictwa, i nasze usługi opisują klientowi, czym są te metody i czy mają one skutki uboczne?

Zasadniczo mam wrażenie, że opis struktury zasobów po stronie serwera jest równoważny z definicją słownictwa, ale jesteśmy zmuszeni do używania ograniczonego słownictwa do interakcji z tymi zasobami.

Czy ustalone słownictwo naprawdę oddziela obawy klienta od obaw serwera? Z pewnością muszę się martwić pewną konfiguracją serwera, zwykle jest to lokalizacja zasobów w usługach RESTful. Narzekanie na użycie dynamicznego słownictwa wydaje się niesprawiedliwe, ponieważ i tak musimy dynamicznie zastanawiać się, jak zrozumieć tę konfigurację. Usługa RESTful opisuje przejścia, które możesz wykonać, identyfikując strukturę obiektu za pomocą hipermediów.

Po prostu nie rozumiem, co sprawia, że ​​stałe słownictwo jest lepsze niż jakiekolwiek samoopisujące się słownictwo dynamiczne, które z łatwością mogłoby działać bardzo dobrze w serwisie podobnym do RPC. Czy to tylko słabe uzasadnienie ograniczającego słownictwa protokołu HTTP?

Odbicie

Żeby wyjaśnić moje myśli trochę lepiej niż ja. Załóżmy, że projektujesz interfejs API ogólnego przeznaczenia, a może nawet nie jest on obsługiwany przez Internet. Czy byłbyś szczęśliwy, gdyby ktoś powiedział, że możesz używać tych nazw metod tylko na swoich obiektach? REST nie jest ograniczony do HTTP, ale weź pod uwagę sytuację, w której każdy napisany interfejs API, strona internetowa lub w inny sposób po prostu składa się z obiektów zawierających metody GET POST PUT i DELETE. Tak więc metoda object.foo, którą chciałeś zdefiniować, nie jest możliwa. Musisz zdefiniować nowy obiekt o nazwie foo i wywołać jego metodę GET. Zasadniczo tak działa REST i sprawia, że ​​myślę o tym trochę niewygodnie. Nie masz lepszego ogólnego zrozumienia tego, co robi Foo, po prostu zmuszono Cię do utworzenia nowego obiektu, który jest zasadniczo metodą na obiekcie nadrzędnym. Ponadto Twój interfejs API jest nie mniej złożony, właśnie ukryłeś złożoność interfejsu, tworząc więcej obiektów. Usługi sieci Web RESTful zmuszają nas do przyjęcia interfejsu, który może, ale nie musi być wystarczający w kontekście interfejsu API, który udostępniamy. Być może istnieje dobry powód, aby to zrobić z interfejsami API skierowanymi do Internetu, ale jest to dobry powód, aby nie przyjmować standardowych interfejsów dla każdego obiektu w każdym interfejsie API ogólnego przeznaczenia. Doceniony zostanie praktyczny przykład.

Matt Esch
źródło
Aby pomóc użytkownikom w szybkim analizie pytania i odpowiedzi, możesz rozważyć dodanie „Aktualizacji” jako osobnych odpowiedzi (szczególnie w sekcji „Kolejna aktualizacja”). Zachęcamy: blog.stackoverflow.com/2011/07/…
Johann
@Johann dzięki, dalsze aktualizacje już istnieją jako akceptowana odpowiedź na to pytanie.
Matt Esch

Odpowiedzi:

9

Terminologia „czasownik” i „rzeczownik” jest tutaj nieco niefortunna. Jak już wspomniałeś, możesz łatwo stworzyć obiekt dla funkcji. Wszystkie języki zorientowane obiektowo oprócz Java mają tę wbudowaną transformację, a w Javie robisz to cały czas i tak kończysz się mnóstwem obiektów za pomocą jednej metody i często o nazwie „invoke”, „execute”, „Apply” lub jakoś tak (więc w językach programowania rozróżnienie „czasownik” / „rzeczownik” faktycznie nie ma sensu).

„Czasowniki” REST bardziej przypominają klasyfikowanie metod do pobierających, ustawiających (usuwających; można je uważać za ustawiające) i innych. I próbowanie zrobienia wszystkiego z pobierającymi i ustawiającymi. Powodem tego jest:

  1. Łatwiejsza semantyka w obliczu awarii komunikacji, ponieważ zarówno pobierający, jak i ustawiający są idempotentni. Dwukrotne uzyskanie zasobu nie ma żadnego dodatkowego efektu i nie ustawia go na wartość, którą już ma.
  2. Definiowanie niektórych semantyki, które mogą być używane przez buforowanie proxy, które nie rozumie określonego interfejsu. Pobieracze są buforowane, a znane są, że unieważniają pamięć podręczną.

HTTP został zaprojektowany od samego początku z myślą o buforach i odporności na uszkodzenia, więc te dwa punkty prowadzą do czterech podstawowych metod:

  • GETjest łapaczem. Zakłada się, że nie modyfikuje stanu serwera i zwraca tę samą wartość za każdym razem z możliwością określenia zasad dotyczących wygaśnięcia i ponownej walidacji.
  • PUTi DELETEsą seter i deleter (= seter z zerem). Nie są zwykle używane w kontekście normalnej sieci, ale mają sens dla REST.
  • POST to ogólny zlew kuchenny „invoke”, dla którego pamięci podręczne nic nie zakładają.

REST to wzorzec projektowy opisujący, jak używać surowego protokołu HTTP lub podobnych protokołów sieciowych do implementacji interfejsu, który umożliwia łatwą obsługę awarii przez proste ponawianie i działa dobrze z buforującymi serwerami proxy.

Nie odpowiada łatwo zwykłemu obiektowemu API programowania. Myślę, że to naprawdę dobra rzecz. Wyzwania związane z interfejsem sieciowym, który jest z natury zawodny i gdzie zwroty są znacznie wolniejsze niż przesyłanie nawet umiarkowanej ilości danych, wymagają innego podejścia projektowego niż interfejs API w procesie, więc kiedy wygląda inaczej, ludzie nie próbują aplikować niepoprawne doświadczenie z drugiej domeny tak bardzo (to zmora SOAP, XML-RPC i tak dalej; wygląda na wywołania procedur, ale nie działa w ten sposób i kończy się z tym bólem).

Jan Hudec
źródło
2

Podstawową ideą jest to, że złożoność jest wyrażana poprzez reprezentację zasobów, a zatem dodatkowe czasowniki nie są potrzebne. Jak niektórzy to powiedzieli - „W REST rzeczowniki są dobre, czasowniki złe”.

Jeśli spojrzysz na cztery czasowniki REST, można je odwzorować na podstawowe operacje CRUD, co zasadniczo pozwala ci robić, co chcesz, z wykorzystaniem zasobów. To jest -

POST - Utwórz zasób

GET - przeczytaj zasób

PUT - Zaktualizuj zasób

USUŃ - Usuń zasób

Co jeszcze potrzebujesz?

Craig Schwarze
źródło
Mogę ułatwić czasownik w usłudze RESTful, tworząc zasób do jego wykonania. Jak mówisz, nie potrzebuję dodatkowych czasowników, tylko więcej zasobów. Po prostu nie rozumiem, dlaczego lepiej udawać, że jakikolwiek abstrakcyjny czasownik jest rzeczownikiem, gdy tak naprawdę chcę to czasownik. Wygląda na to, że czasowniki są przymusowo ograniczane bez powodu, a ja unikam tego problemu, tworząc rzeczowniki, które wykonują wymagane czynności, gdy są dostępne za pomocą małego zestawu czasowników. Dlaczego miałoby to być lepsze? Musi być dobry powód, coś, co mogę określić jako praktyczny przykład.
Matt Esch,
4
Uzyskaj listę wszystkich zasobów, uzyskaj listę wszystkich zasobów z określonymi ograniczeniami, zaktualizuj lub usuń wiązkę zasobów jednocześnie, utwórz dwa różne typy zasobów razem atomowo (tak, aby oba tworzenie zakończyło się niepowodzeniem lub zakończyło się sukcesem), usuń wszystkie zasoby spełnienie danego warunku ... Lista rzeczy, które można zrobić, jest dość długa. Można je dopasować do interfejsu API REST, ale nie zawsze jest to naturalne. Nie pomaga również to, że GET nie pozwala na treść, więc złożone warunki filtrowania stają się podobne.
Andrea,
ŁADOWANIE zasobów jest również całkiem fajne.
Wyatt Barnett
2

Rozważ język, w którym wszystkie konstrukcje (takie jak funkcje) są obiektami. Następnie czasowniki RESTful wywołują konwencje i instrukcje przypisania. W przypadku JavaScript można zdefiniować stałą składnię czasownika, np. INVOKE do wywoływania funkcji, DELETE (to samo, co delete w js) do usuwania obiektu z innego obiektu, SET do przypisywania wartości i RETURN do zwracania wartości. Możemy użyć czasowników HTTP, aby oznaczać równoważne POST - funkcja wywoływania, PUT - przypisywanie wartości, GET - zwracanie wartości, - DELETE - usuwanie obiektu. Byłem pochłonięty pomysłem, że metody HTTP faktycznie opisują metody obiektowe, rzeczywiste interfejsy obiektowe, że nie zauważyłem, że może on faktycznie opisywać pojęcia znacznie niższego poziomu, takie jak podstawowe konstrukcje języka, które są wyraźnie ustalone i skończone we wszystkich rozsądne języki.

I oczywiście przydatne dla routingu / proxy jest posiadanie ustalonego słownictwa do refleksji.

Matt Esch
źródło
1
  • Ponieważ profesjonalny programista przewiduje setki, jeśli nie tysiące nazw metod. To, co wydaje się bezcelowe w przypadku mniejszych małych, może być bardzo duże, ponieważ aplikacja staje się większa.

  • Ponieważ nie ma potrzeby standardów dotyczących nazw metod, gdy są one już zdefiniowane.

  • Ponieważ główny cel kodu jest czytelny bez takich dodatkowych tłumaczeń.

  • Ponieważ zachęca i pomaga w określeniu „kiedy” należy wykreślić inną klasę.

  • Po przejęciu kodu rozsądne i faktycznie jest możliwe, aby zrozumieć, co i jak robi to znacznie szybciej.

  • Zapewnia wspólne słownictwo, a tym samym poziom abstrakcji, dzięki czemu możesz skupić się na innych szczegółach i zobaczyć wzory.

  • Ułatwia to znajdowanie błędów, ponieważ można łatwo sprawdzić wspólny kod i podejścia.

  • Podczas pracy z wieloma „warstwami”, takimi jak jedna przy tworzeniu stron internetowych, wiedza o tym, które adresy URL pasują do których nazw akcji jest bardzo przydatna do debugowania.

Ogólnie rzecz biorąc, nie zawsze go potrzebujesz, ale podobnie jak większość standardów, warto próbować go używać!

Michael Durrant
źródło
Adresowane w kolejności 1) Czyli programista przewiduje setki, jeśli nie tysiące zasobów, inaczej? Już przewidujemy metody w używanych przez nas bibliotekach. 2) Więc potrzebujemy standardów dla nazw metod, ale nie dla nazw zasobów? Nie przestrzegam tej logiki. 3) Nie jestem pewien, co rozumiesz przez tłumaczenia. Jeśli powiesz mi, że istnieje zasób, muszę go zrozumieć. Jeśli powiem ci, że istnieje metoda, musisz ją zrozumieć. Jedyne, na czym mi zależy, to które z moich działań będą miały skutki uboczne 4) Czy możesz rozwinąć
Matt Esch
5) ponownie możesz rozwinąć. Jestem programistą. Jestem przyzwyczajony do pracy z dobrze zdefiniowanymi strukturami obiektowymi. Dlaczego nie mielibyśmy używać tego samego mechanizmu do definiowania wszystkich naszych interfejsów API, jeśli jest naprawdę lepszy? 6) Żaden poziom abstrakcji nie jest wart rozważenia bez uzasadnienia. 7) Znowu możesz się rozwinąć. Jeśli skorzystamy w ten sposób, z pewnością powinniśmy kodować wszystkie nasze interfejsy API w ten sposób. 8) Oczekiwałbym, że jakikolwiek obiekt bezpośrednio ujawni swoje metody. Nie można pomylić metody / object /. Standardy określamy, wybierając je. W tej chwili brakuje mi motywacji.
Matt Esch,
Matt, wydajesz się trochę kłótliwy, ale powiem, że dla 2) nie powiedziałem, że zasób nie będzie wymagał standardów 3) Nie będziesz musiał rozumieć metody takiej jak „aktualizacja” lub „nowa” lub tworzenie ”, ponieważ dokładnie wiesz co robią zgodnie ze standardami. Co jednak z „MsgToPrimary”, co to robi? Utworzyć wiadomość? Zaktualizować status? Wyślij e-mail? 7) Tak, większość interfejsów API mogłaby z tego skorzystać i wiele z nich. Spróbuję się skupić na pojęciu, że standardowe standardy i konwencje są pomocne i widzę, że twoje aktualizacje to pokazują.
Michael Durrant,
Po prostu staram się zrozumieć korzyści. Aby wyjaśnić problem, należy zająć się silnymi kontrargumentami. Nadal rozumiem, że ustalony zestaw czasowników jest rodzajem opisu języka, ale tak naprawdę nie zgadzam się, że łatwiej to zrozumieć. Nie można zabrać ekspresyjnego zestawu czasowników i powiedzieć: hej, teraz rozumiemy wszystkie czasowniki, gdy nie rozumiemy wszystkich zasobów. Zasoby zastępują czasowniki. Zastępujemy dowolny czasownik foo zasobem o nazwie foo. Nasze rozumienie foo nie jest bardziej jasne niż wtedy, gdy foo było czasownikiem.
Matt Esch,
1

Alternatywą jest coś strasznego: WSDL (inaczej Web Service Definition Language), który jest (niezdarny) sposobem na programowe opisanie (nieco) arbitralnego APIS.

REST poważnie ogranicza czasowniki, przesuwając prawie całą zmienność specyficzną dla aplikacji do ładunku dokumentu. Zaletą tego jest to, że wiele implementacji klientów może komunikować się z wieloma heterogenicznymi usługami. Klienci i serwery mogą być dla siebie zupełnie nieznani, niektórzy jeszcze nie są zapisani.

Jest podcast, w którym Stefan Tilkov ładnie wyjaśnia REST .

care
źródło
1

Tak, reszta interfejsu API ma stały zestaw czasowników, ale nie musi być ograniczony do (lub obejmuje GET, POST, PUT, DELETE). Patrzyłbym na GET, POST, PUT, DELETE jako domyślną implementację REST, która działa dla 80% wszystkich dostępnych systemów.

Inne systemy, które wdrażają więcej niż operacje crud, mogą (i robią) implementować własne czasowniki dla swoich interfejsów API REST. Czasowniki takie jak Publikuj, Używaj, Oceń, Komentuj, Szukaj, Przeglądaj można dodawać i implementować w systemie REST. Chociaż niektórzy mogą powiedzieć, że większe słownictwo może sprawić, że będzie bardziej skomplikowane, moja odpowiedź jest taka, że ​​to zależy. Jeśli docelowym użytkownikiem są główni technicy, którzy rozumieją, czym jest POST, to tak, może być bardziej skomplikowane; jednak jeśli docelowymi użytkownikami interfejsu API są prawdziwi ludzie (tj. ludzie, którzy nie kodują i nie wiedzą, czym jest POST), wówczas prawdziwe czasowniki są znacznie łatwiejsze w użyciu. Właściwie posiadanie odpowiedniego zestawu czasowników dla twojego API pomaga skrócić adresy URL (co jest ważne, jeśli chcesz, aby użytkownicy wpisywali je w przeglądarce. Jeśli używasz niestandardowego słownictwa, „ d chcę się upewnić, że interfejs API i jego czasowniki są dobrze udokumentowane. Korzystając z niestandardowego interfejsu API REST, należy się upewnić, że „akcje tylko do odczytu” jako HTTP GET i „akcje zapisu” z POST.

Sieć społecznościowa dla nastolatków Piczo.com (niech spoczywa w pokoju) zawierała rozszerzony interfejs API REST (w tym czasowniki wspomniane powyżej), który został zaimplementowany w 7 różnych językach!

Andrzej
źródło
0

Proste jest dobre.

Są przypadki, gdy potrzebujesz dodatkowych czasowników i złożoności, ale większość problemów można ograniczyć do prostych działań CRUD na zasobach, i to właśnie REST próbuje promować. Kiedy myślisz o większości aplikacji internetowych, w końcu odczytują i przechowują rekordy w magazynie danych, które używają tych samych, bardzo prostych akcji.

Object.foo () jest dobry, ale co on robi? Co to powraca? Czy modyfikuje stan obiektu lub jego zależności? Czy możesz to nazwać dwa razy i uzyskać ten sam wynik, czy da ci dwie różne wartości? Jeśli masz także object.bar (), czy trzeba je wywoływać w określonej kolejności?

Korzystanie z bogatego interfejsu API wymaga dużej wiedzy i zwykle mają one swoje własne konwencje (tzn. SetFoo zmutuje obiekt, getBar prawdopodobnie jest idempotentny, dispose () lub destroy () oznacza, że ​​nie ma innych wywołań tego samego obiektu będzie możliwe itp.)

ptyx
źródło