Dlaczego w aplikacjach internetowych powszechnie stosuje się REST zamiast mechanizmów podobnych do RPC?

18

Zacząłem bardzo niedawno w firmie, która używa dość niestandardowych ram dla swoich aplikacji internetowych, przynajmniej w porównaniu z typowymi platformami aplikacji internetowych, które znam. Zamiast usługi sieci web RESTful do komunikacji z serwerem wykorzystywany jest mechanizm RPC.

Komunikacja z serwerem wygląda jak proste wywołanie funkcji, ale funkcja jest wykonywana na serwerze, a nie na kliencie. Po stronie serwera można zdefiniować funkcje, które klient może wywoływać. Szczegóły, w jaki sposób jest to tłumaczone na żądania HTTP, są całkowicie oderwane.

Użyłem tego dopiero od niedawna, ale wydaje się to całkiem wygodne. Ale zastanawiam się, jakie wady tego podejścia mi brakuje. Wszyscy inni robią to inaczej, co zwykle jest dla mnie znakiem, że robię coś głupiego lub genialnego, ze znacznie wyższymi szansami na to pierwsze.

Vivian
źródło
5
Chciałbym odgadnąć (ale nie jestem w 100% pewien, więc będę po prostu zostawić to jako komentarz i niech ktoś, kto naprawdę zna się na rzeczy umieścić właściwą odpowiedź), że reszta jest używany więcej niż RPC ponieważ interfejsy REST są zwykle łatwiejsze do wdrożenia i są mniej zależne od konkretnych podstawowych ram / technologii.
FrustratedWithFormsDesigner
11
Mam wrażenie, że większość klientów REST bardziej zależy na prostym interfejsie API http + json niż na samym REST.
CodesInChaos
4
Ponieważ cała branża oszalała.
Mike Nakis
Może Cię to zainteresować stackoverflow.com/q/15056878/5934037
Laiv
1
Sporna opinia: w przeważającej części różnice między REST i RPC są w większości akademickie.
whatsisname

Odpowiedzi:

33

REST został zaprojektowany dla Internetu, a sieć została zaprojektowana dla REST. Oba pasujące po prostu pasują do siebie. Praca doktorska Roya Fieldinga z 2000 r. Style architektoniczne i projektowanie architektur oprogramowania sieciowego zdefiniowały i wprowadziły pojęcie REST , a sieć i REST są w znacznym stopniu powiązane: Roy Fielding pracował nad HTTP / 1.1, którego jest głównym autorem, i wykorzystał to, czego się tam nauczył, aby opisać REST w swojej rozprawie.

Tak więc prostym powodem, dla którego sieć i REST są tak dobrze ze sobą powiązane, jest to, że definicja REST została wyodrębniona z tego, jak działa sieć, a sieć jest implementacją REST.

Właśnie dlatego REST dobrze nadaje się do usług internetowych i aplikacji internetowych: ponieważ po prostu robisz te same rzeczy, które już udowodniono, że działają w „ludzkiej” sieci i stosujesz je w sieci „maszynowej”.

Duży problem z RPC (w zależności od dokładnej realizacji) leży w zasadzie w błędom Distributed Computing , które zostały wyjaśnione w sposób bardziej szczegółowy w ten oficjalny dokument przez Arnon Rotem-gal Oz :

  1. Sieć jest niezawodna
  2. Opóźnienie wynosi zero
  3. Przepustowość jest nieskończona
  4. Sieć jest bezpieczna
  5. Topologia się nie zmienia
  6. Jest jeden administrator
  7. Koszt transportu wynosi zero
  8. Sieć jest jednorodna

Są to wszystkie założenia, które zwykle przyjmują nowi użytkownicy, kiedy zaczynają tworzyć systemy rozproszone. Oczywiście wszystkie z nich są fałszywe. I musisz wziąć je wszystkie pod uwagę przy tworzeniu systemów rozproszonych.

Problem z wieloma implementacjami RPC polega na tym, że starają się, aby połączenia zdalne wyglądały jak połączenia lokalne. Ale nie są niczym:

  • połączenie lokalne nigdy nie kończy się niepowodzeniem; podprogram , który nazywa może zawieść, ale rozmowa sama nigdy nie robi - zdalne wywołanie może zgubić się w sieci
  • połączenie lokalne jest natychmiastowe; podprogram , który nazywa może działać przez długi czas (lub nawet na zawsze, jeśli utknie w nieskończonej pętli), ale rozmowa sama bierze w ogóle czasu (no, garść instrukcji procesora co najwyżej mniej, jeśli połączenie jest podkreślone, ale jest bardzo szybki) - zdalne połączenie może utknąć w sieci na długi czas
  • jeśli podprogram powróci normalnie, wynik zawsze wraca - po zdalnym wywołaniu wynik może zostać utracony w sieci
  • zwroty są natychmiastowe - wyniki zdalne mogą długo podróżować w sieci
  • jeśli raz wywołam podprogram, uruchomi się dokładnie raz - zdalne połączenie może zostać utracone w sieci lub zduplikowane, więc procedura zdalna może działać od 0 do dowolnej liczby razy
  • Otrzymuję dokładnie jeden wynik - zdalny wynik może zostać zgubiony lub zduplikowany, więc możesz uzyskać wynik 0 lub więcej razy
  • jeśli dwukrotnie wywołam podprogram, otrzymam dwa wyniki i otrzymam wynik pierwszego wywołania przed wynikiem drugiego wywołania - prawdopodobnie prawdopodobnie już się domyślacie: z RPC możesz nie otrzymać żadnych wyników lub tylko pierwszego , lub tylko druga, druga przed pierwszą lub pierwsza może zostać utracona, a drugą otrzymasz dwa razy, lub odwrotnie, i tak dalej ...
  • jeśli zadzwonię, aa następnie bodzyskam wynik, aa następnie wynik b - to tylko bardziej ogólna wersja poprzedniego punktu, z RPC, możesz uzyskać dowolną z dwóch odpowiedzi 0 lub więcej razy w dowolnej kolejności

Państwo będzie mieć do czynienia z wszystkich wyżej dla zdalnego wywołania. Ale jeśli twoja struktura sprawia, że ​​połączenia zdalne są nierozróżnialne od połączeń lokalnych, nie możesz tego zrobić, ponieważ nie wiesz, które z nich to połączenia zdalne. Framework może próbować obsłużyć je wszystkie, ale problem polega na tym, że framework nie wie tyle o twoim systemie, co ty. Nie wie, czy są połączenia, w których to tak naprawdę nie ma znaczenia, czy ktoś się zgubi raz na jakiś czas. Ramy muszą więc być bardzo defensywne, a to jest kosztowne ze względu na opóźnienia i przepustowość.

Zwłaszcza, że ​​ramy nie mogą cię ochronić. CAP Twierdzenie mówi, że rozproszony system nie może być spójne, dostępne, i partycji-tolerancyjny w tym samym czasie; a dokładniej mówi, że po wystąpieniu partycji system nie może być zarówno spójny, jak i dostępny, musi wybrać jedną (wbrew powszechnemu przekonaniu twierdzenie nie mówi, że nie można mieć wszystkich trzech, gdy system działa) normalnie możesz mieć wszystkie trzy, ale kiedy już masz Partycję, musisz wybrać jedną z dwóch pozostałych). PACELC Twierdzenie rozszerza CAP twierdzenie, pokazując, że nawet, gdy system działa, trzeba kompromis Latency vs. konsystencji.

Są to ważne kompromisy, przed którymi ramy właściwie nie są w stanie cię ochronić, ponieważ są specyficzne dla domeny i ważne dla rdzenia.

Porównajmy to z podejściem jak Erlang, co czyni pracę: w Erlang, wszystkie wiadomości wysyła są traktowane jako odległe, nawet jeśli są one lokalne. Oznacza to, że zawsze jesteś przygotowany na wszystkie powyższe problemy (i wiele innych). Dla procesów lokalnych, te nie stwarzają trochę narzutem, choć. Aby temu zaradzić, istnieje wiele narzędzi, struktur, bibliotek, wzorców i idiomów służących do obsługi błędów i nadzoru.

Nie opisałeś, w jaki sposób działa Twój framework RPC i jakiego języka lub bibliotek używasz, ale mam poważne podejrzenia, że ​​należy on do poprzedniego typu „udawaj, że sieć nie istnieje”. Te po prostu nie działają. To jest w porządku , aby usunąć rozróżnienie połączeń lokalnych i zdalnych traktując wszystko jako zdalnego połączenia. Robiąc to w drugą stronę, zbyt wiele abstrakcji: sieć jest częścią twojego systemu, jeśli ją abstraktujesz, wyodrębniasz coś, o czym naprawdę musisz wiedzieć.

Teraz, czy trzeba specjalnie użyć REST, czy nie, to zupełnie inna kwestia. Jak wyjaśniłem powyżej, sieć została zaprojektowana dla REST, a REST została zaprojektowana dla sieci, więc oba mają sens razem, ale możesz użyć innych stylów architektonicznych, jeśli chcesz. Ale przynajmniej część twojego pytania dotyczyła „dlaczego nie RPC”, a ja przedstawiłem powyższe powody, a dokładniej wyjaśniłem, dlaczego rodzaj RPC, którego podejrzewasz, że używasz, może wpędzić cię w kłopoty.

Jörg W Mittag
źródło
Czy standaryzacja nie stanowi również problemu (biorąc pod uwagę brak mapowania 1: 1 między HTTP a RPC)?
Jimmy T.
Cóż, istnieją ramy modelu aktora, które rozwiązują wszystkie te problemy.
Robert Harvey,
Oczywiście wystarczy entuzjastyczna osoba do stworzenia warstwy abstrakcji w interfejsie REST i szybko staje się ona nie do odróżnienia od interfejsu RPC.
whatsisname
1
Kolejny błąd przetwarzania rozproszonego: klienci i serwery aktualizują się w tym samym czasie.
Jack
@Jack: Jest to błędne stwierdzenie „Istnieje tylko jeden administrator”. W białej księdze wspomniano:…
Jörg W Mittag,
5

W komentarzach jest już kilka dobrych pomysłów, które powtórzę tutaj:

  1. RPC jest zazwyczaj specyficzne dla technologii.
  2. To, co najbardziej interesuje deweloperów, to JSON, a nie REST.

JSON ma kilka bardzo fajnych cech. Jest prosty, łatwy do odczytania przez człowieka, łatwy do parsowania przez komputer, a JavaScript natychmiast rozpoznaje go natywnie (jest to, no wiesz, notacja obiektowa JavaScript ).

Jeśli chcesz zrezygnować z ograniczeń, takich jak REST, możesz zrobić prawie wszystko, co chcesz z JSON, w tym zdalne wywołania procedur. Wszystko, co musisz zrobić, to ustalić odpowiedni protokół. W rzeczywistości taki protokół już istnieje: JSON-RPC.

--> {"jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1}
<-- {"jsonrpc": "2.0", "result": 19, "id": 1}
Robert Harvey
źródło
-1

RPC i REST to tylko różne podejścia z zaletami i wadami, i oba są wartościowe w zależności od kontekstu. REST najlepiej opisać do pracy z zasobami, ponieważ w RPC chodzi bardziej o działania. Klienci RPC są ściśle powiązani z implementacją usług na kilka sposobów i bardzo trudno jest zmienić implementację usługi bez rozbijania klientów.

Kamal Hossain
źródło