Interfejs API Websocket zastąpi REST API?

102

Mam aplikację, której podstawowa funkcja działa w czasie rzeczywistym, poprzez websockets lub długie odpytywanie.

Jednak większość witryny jest napisana w sposób RESTful, co jest przyjemne dla aplikacji i innych klientów w przyszłości. Jednak myślę o przejściu na interfejs API sieci Web dla wszystkich funkcji witryny, z dala od REST. Ułatwiłoby mi to integrację funkcji czasu rzeczywistego we wszystkich częściach witryny. Czy utrudniłoby to tworzenie aplikacji lub klientów mobilnych?

Odkryłem, że niektórzy ludzie już robią takie rzeczy: SocketStream

Złupić
źródło
2
Długie odpytywanie @Stegi działa wystarczająco dobrze jako rozwiązanie zastępcze, nie przejmując się tym zbytnio.
Harry,
2
Harry teraz, po 7 latach, jak ci się to udało? Zastanawiam się, skoro ja też chcę iść w tym kierunku. @Harry
Dmitry Kudryavtsev
2
@DmitryKudryavtsev Ostatecznie tego nie zrobiłem. Tradycyjna metoda działała dobrze i nie była dużo trudniejsza.
Harry,

Odpowiedzi:

97

Nie mówiąc o tym, że inne odpowiedzi tutaj nie mają wartości, mają kilka dobrych punktów. Ale mam zamiar sprzeciwić się ogólnemu konsensusowi i zgodzić się z wami, że przejście na WebSockets w celu uzyskania czegoś więcej niż tylko funkcji czasu rzeczywistego jest bardzo atrakcyjne.

Poważnie rozważam przeniesienie mojej aplikacji z architektury RESTful do stylu RPC za pośrednictwem gniazd internetowych. To nie jest „aplikacja do zabawy” i nie mówię tylko o funkcjach działających w czasie rzeczywistym, więc mam zastrzeżenia. Ale widzę wiele korzyści z pójścia tą trasą i czuję, że może to być wyjątkowe rozwiązanie.

Mój plan zakłada użycie DNode , SocketIO i Backbone . Dzięki tym narzędziom moje modele i kolekcje Backbone mogą być przekazywane z / do klienta i serwera, po prostu wywołując funkcje w stylu RPC. Koniec z zarządzaniem punktami końcowymi REST, serializacją / deserializacją obiektów i tak dalej. Nie pracowałem jeszcze z gniazdem, ale wygląda na to, że warto to sprawdzić.

Przed nami jeszcze długa droga, zanim definitywnie stwierdzę, że jest to dobre rozwiązanie i jestem pewien, że nie jest to najlepsze rozwiązanie dla każdego zastosowania, ale jestem przekonany, że to połączenie byłoby wyjątkowo potężne. Przyznaję, że są pewne wady, jak na przykład utrata możliwości buforowania zasobów. Ale mam wrażenie, że zalety przeważą nad nimi.

Byłbym zainteresowany śledzeniem twoich postępów w odkrywaniu tego typu rozwiązań. Jeśli masz jakieś eksperymenty na githubie, wskaż mi je. Jeszcze nie mam, ale mam nadzieję, że wkrótce.

Poniżej znajduje się lista linków do przeczytania później, które zebrałem. Nie mogę ręczyć, że wszystkie są warte zachodu, ponieważ tylko przejrzałem wiele z nich. Ale miejmy nadzieję, że niektórzy pomogą.


Świetny samouczek dotyczący używania Socket.IO z Express. Udostępnia sesje ekspresowe do socket.io i omawia, jak mieć różne pokoje dla każdego uwierzytelnionego użytkownika.

Samouczek dotyczący node.js / socket.io / backbone.js / express / connect / jade / redis z uwierzytelnianiem, hostingiem Joyent itp .:

Samouczek dotyczący używania Pushera z Backbone.js (przy użyciu Railsów):

Zbuduj aplikację za pomocą backbone.js na kliencie i node.js z express, socket.io, dnode na serwerze.

Używanie Backbone z DNode:

Tauren
źródło
1
Właśnie odpowiedziałem na pokrewne pytanie i zawarłem kilka dodatkowych przemyśleń: stackoverflow.com/questions/4848642/ ...
Tauren.
12
„Pozostało jeszcze wiele do zrobienia, zanim definitywnie stwierdzę, że to dobre rozwiązanie” - tylko ciekawość, czy to naprawdę dobre rozwiązanie? : D
inf3rno
7
Prosimy o odpowiedź @Tauren. Jestem bardzo zainteresowany tym, co masz teraz do powiedzenia.
No_name
4
@Tauren Jestem również ciekawy, jak to się udało?
Kurren
57

HTTP REST i WebSockets są bardzo różne. Protokół HTTP jest bezstanowy , więc serwer sieciowy nie musi nic wiedzieć, a buforowanie w przeglądarce internetowej i na serwerach proxy. Jeśli używasz WebSockets, twój serwer staje się stanowy i musisz mieć połączenie z klientem na serwerze.

Komunikacja typu żądanie-odpowiedź a funkcja Push

Używaj WebSockets tylko wtedy, gdy potrzebujesz PUSH danych z serwera do klienta, ten wzorzec komunikacji nie jest uwzględniony w HTTP (tylko przez obejścia). Funkcja PUSH jest pomocna, jeśli zdarzenia utworzone przez innych klientów muszą być dostępne dla innych podłączonych klientów, np. W grach, w których użytkownicy powinni działać na zachowanie innych klientów. Lub jeśli Twoja witryna coś monitoruje, gdzie serwer cały czas przesyła dane do klienta, np. Giełdy (na żywo).

Jeśli nie potrzebujesz PUSH danych z serwera, zwykle łatwiej jest użyć bezstanowego serwera HTTP REST. HTTP używa prostego wzorca komunikacji żądanie-odpowiedź .

Jonas
źródło
5
Jesteśmy bardzo przyzwyczajeni do wzorca jednokierunkowego, ponieważ nigdy wcześniej nie mieliśmy żadnych alternatyw. Ale teraz, gdy moja aplikacja staje się bardziej rozwinięta, stało się dla mnie bardziej oczywiste, że im więcej miejsc, w których używana jest technologia push, tym bardziej responsywna i bardziej angażująca staje się aplikacja.
Harry,
Moja aplikacja wyświetla listę znajomych i na przykład liczbę posiadanych przez nich punktów. Dlaczego nie zaktualizować go w czasie rzeczywistym. Jeśli użytkownicy widzą postępy swoich znajomych, mogą być bardziej skłonni do nadrobienia zaległości. Mam pewne modele dokumentów, które choć nie zmieniają się często, są na tyle zmieniane, że brak ich aktualizacji w czasie rzeczywistym może spowodować niewielkie zamieszanie. W pewnym momencie wystarczająca część witryny korzysta z aktualizacji push, że zaczynasz patrzeć na swój kod, a połowa z niego dotyczy REST, a druga połowa dotyczy gniazd i dobrze mówisz, chcę to ujednolicić.
Harry
3
Jest to opcja, aby używać websockets tylko do wysyłania powiadomienia / polecenia do twojej aplikacji internetowej (jak getUpdate lub refreshObjectWithId z params). Polecenie to może zostać przeanalizowane w aplikacji sieciowej (kliencie), a następnie żądanie odpoczynku w celu pobrania określonych danych zamiast przesyłania danych przez gniazda sieciowe.
Beachwalker
2
Istnieje wiele powodów, dla których websockets mogą być łatwiejsze niż wywołania REST - nie tylko w przypadku wypychania. websocket.org/quantum.html
BT,
WebSockets są niesamowite i pozwalają serwerowi wysyłać dane klienta w dowolnym momencie, nie tylko w odpowiedzi na wiadomość klienta. WebSockets implementuje protokół oparty na komunikatach, dzięki czemu klienci mogą odbierać wiadomości w dowolnym momencie, a jeśli czekają na konkretną wiadomość, mogą kolejkować inne wiadomości do późniejszego przetworzenia, zmieniać kolejność wiadomości w kolejce, ignorować wypychane wiadomości w zależności od stanu aplikacji itp. Nigdy więcej nie napiszę innej aplikacji opartej na REST. Flash również to ułatwia dzięki implementacjom WebSocket opartym na AS3 typu open source i możliwości powrotu do przeglądarki za pośrednictwem metod ExternalInterface. (AddCallback / call).
Triynko
41

Myślę o przejściu na interfejs API WebSocket dla wszystkich funkcji witryny

Nie. Nie powinieneś tego robić. Nie ma nic złego, jeśli wspierasz oba modele. Użyj REST do komunikacji jednokierunkowej / prostych żądań i WebSocket do komunikacji dwukierunkowej, zwłaszcza gdy serwer chce wysyłać powiadomienia w czasie rzeczywistym.

WebSocket jest bardziej wydajnym protokołem niż RESTful HTTP, ale nadal RESTful HTTP uzyskuje wyniki w porównaniu z WebSocket w poniższych obszarach.

  1. Tworzenie / aktualizowanie / usuwanie zasobów zostało dobrze zdefiniowane dla protokołu HTTP. Musisz zaimplementować te operacje na niskim poziomie dla WebSockets.

  2. Połączenia protokołu WebSocket skalują się w pionie na jednym serwerze, podczas gdy połączenia HTTP skalują się w poziomie. Istnieje kilka zastrzeżonych niestandardowych rozwiązań dla skalowania poziomego WebSocket.

  3. HTTP ma wiele dobrych funkcji, takich jak buforowanie, routing, multipleksowanie, gzipping itp. Jeśli wybrałeś Websocket, muszą one być oparte na Websocket.

  4. Optymalizacje wyszukiwarek działają dobrze w przypadku adresów URL HTTP.

  5. Wszystkie serwery proxy, DNS i zapory nie są jeszcze w pełni świadome ruchu w sieci WebSocket. Pozwalają na port 80, ale mogą ograniczyć ruch, najpierw go szpiegując.

  6. Bezpieczeństwo dzięki WebSocket to podejście typu wszystko albo nic.

Więcej informacji znajdziesz w tym artykule .

Ravindra babu
źródło
3
To najlepsza odpowiedź.
MattWeiler,
1
Najlepsza odpowiedź na ten temat
Sanandrea
10

Jedynym problemem, jaki mogę zastosować przy używaniu protokołu TCP (WebSockets) jako głównej strategii dostarczania treści internetowych, jest to, że jest bardzo mało materiałów do czytania na temat projektowania architektury i infrastruktury witryny internetowej przy użyciu protokołu TCP.

Nie możesz więc uczyć się na błędach innych ludzi, a rozwój będzie wolniejszy. Nie jest to również strategia „wypróbowana i przetestowana”.

Oczywiście stracisz również wszystkie zalety HTTP (bycie bezstanowym i buforowanie to największe zalety).

Pamiętaj, że HTTP jest abstrakcją dla protokołu TCP zaprojektowaną do obsługi treści internetowych.

I nie zapominajmy, że SEO i wyszukiwarki nie korzystają z gniazd internetowych. Możesz więc zapomnieć o SEO.

Osobiście odradzałbym to, ponieważ istnieje zbyt duże ryzyko.

Nie używaj WS do obsługi witryn internetowych, używaj go do obsługi aplikacji internetowych

Jeśli jednak masz zabawkę lub osobiste strony internetowe, zdecydowanie idź na to. Spróbuj, bądź nowatorski. W przypadku firmy lub firmy nie można uzasadnić takiego ryzyka.

Raynos
źródło
7

Nauczyłem się małej lekcji (trudna droga). Zrobiłem aplikację do obliczania liczb, która działa w usługach w chmurze Ubuntu AWS EC2 (używa wydajnych procesorów graficznych) i chciałem zrobić dla niej front-end, aby obserwować jej postęp w czasie rzeczywistym. Ze względu na to, że potrzebował danych w czasie rzeczywistym, było oczywiste, że potrzebuję gniazd internetowych do przesyłania aktualizacji.

Zaczęło się od weryfikacji koncepcji i działało świetnie. Ale kiedy chcieliśmy udostępnić go publicznie, musieliśmy dodać sesję użytkownika, więc potrzebowaliśmy funkcji logowania. I bez względu na to, jak na to patrzysz, websocket musi wiedzieć, z którym użytkownikiem ma do czynienia, więc wybraliśmy skrót, używając gniazd sieciowych do uwierzytelniania użytkowników . Wydawało się to oczywiste i było wygodne.

Właściwie musieliśmy spędzić trochę czasu w ciszy, aby połączenia były niezawodne. Zaczęliśmy od kilku tanich samouczków dotyczących technologii WebSocket, ale odkryliśmy, że nasza implementacja nie była w stanie automatycznie połączyć się ponownie, gdy połączenie zostało zerwane. Wszystko się poprawiło, kiedy przeszliśmy na socket-io. Socket-io jest koniecznością!

Powiedziawszy to wszystko, szczerze mówiąc, myślę, że przegapiliśmy kilka świetnych funkcji socket-io. Socket-io ma znacznie więcej do zaoferowania i jestem pewien, że jeśli weźmiesz to pod uwagę w swoim początkowym projekcie, możesz wyciągnąć z niego więcej. W przeciwieństwie do tego, po prostu zastąpiliśmy stare gniazdka sieciowe funkcjonalnością gniazda sieciowego z gniazda-io i to wszystko. (bez pomieszczeń, bez kanałów, ...) Przeprojektowanie mogło sprawić, że wszystko będzie potężniejsze. Ale nie mieliśmy na to czasu. Warto o tym pamiętać w przypadku naszego następnego projektu.

Następnie zaczęliśmy przechowywać coraz więcej danych (historia użytkowników, faktury, transakcje, ...). Przechowaliśmy to wszystko w bazie danych AWS dynamodb i PONOWNIE użyliśmy socket-io do komunikacji operacji CRUD z front-endu do backendu. Myślę, że tam źle skręciliśmy. To był błąd.

  • Ponieważ wkrótce po tym, jak dowiedzieliśmy się, że usługi chmurowe Amazon (AWS) oferują świetne narzędzia do równoważenia / skalowania obciążenia dla aplikacji RESTful .
  • Mamy wrażenie, że musimy napisać dużo kodu, aby wykonać uzgadnianie operacji CRUD.
  • Niedawno wdrożyliśmy integrację Paypal. Udało nam się to uruchomić. Ale znowu, wszystkie samouczki robią to za pomocą RESTful API . Musieliśmy przepisać / przemyśleć ich przykłady, aby zaimplementować je za pomocą gniazd sieciowych. Jednak udało nam się to dość szybko. Ale wydaje się, że idziemy pod prąd.

Powiedziawszy to wszystko, będziemy żyć w przyszłym tygodniu. Dotarliśmy na czas, wszystko działa. Jest szybki, ale czy będzie skalowany?

bvdb
źródło
Zastanawiam się tylko, czy sami próbujemy podjąć tę decyzję, czy dobrze skaluje się z AWS?
Gabe
1
@ Gabe najwyraźniej węzeł może z łatwością przyjąć setki połączeń socket-io w taniej instancji aws. Nie zauważyliśmy jeszcze żadnych problemów z wydajnością. Jednym z dziwnych efektów jest jednak to, że osoby, które raz odwiedzają Twoją witrynę, a następnie zostawiają ją otwartą na karcie, nadal korzystają z połączeń. (i zdarza się to często na telefonach komórkowych). Potrzebujesz więc przynajmniej pewnego rodzaju mechanizmu, aby wyrzucić bezczynnych użytkowników. Jednak nie włożyłem jeszcze w to wysiłku, ponieważ nasza wydajność w ogóle na tym nie cierpi. - Więc nie było jeszcze potrzeby sprawdzania.
bvdb
4

Rozważałbym użycie obu . Każda technologia ma swoje zalety i nie ma jednego uniwersalnego rozwiązania.

Rozdzielenie pracy przebiega następująco:

  1. WebSockets byłyby podstawową metodą komunikacji aplikacji z serwerem, na którym wymagana jest sesja. Eliminuje to wiele hacków, które są potrzebne w starszych przeglądarkach (problemem jest obsługa starszych przeglądarek, która to wyeliminuje)

  2. RESTful API jest używany do wywołań GET, które niezorientowane na sesję (tj. Nie są wymagane uwierzytelnianie), które korzystają z buforowania przeglądarki. Dobrym przykładem mogą być dane referencyjne dla list rozwijanych używanych przez aplikację internetową. Jednak. może zmieniać się nieco częściej niż ...

  3. HTML i Javascript. Obejmują one interfejs użytkownika aplikacji internetowej. Te generalnie przyniosłyby korzyści, gdyby znalazły się w CDN.

  4. Usługi sieci Web używające języka WSDL są nadal najlepszym sposobem komunikacji na poziomie przedsiębiorstwa i między przedsiębiorstwami, ponieważ zapewniają dobrze zdefiniowany standard przekazywania komunikatów i danych. Przede wszystkim przeładowałbyś to na urządzenie Datapower w celu proxy do modułu obsługi usług internetowych.

Wszystko to dzieje się na protokole HTTP, który już teraz zapewnia bezpieczne gniazda przez SSL.

Jednak w przypadku aplikacji mobilnej gniazda sieciowe nie mogą ponownie połączyć się z rozłączoną sesją ( jak ponownie połączyć się z usługą WebSocket po zamknięciu połączenia ), a zarządzanie tym nie jest trywialne. Tak więc w przypadku aplikacji mobilnych nadal polecałbym REST API i odpytywanie.

Inną rzeczą, na którą należy zwrócić uwagę podczas korzystania z WebSockets vs REST, jest skalowalność . Sesje WebSocket są nadal zarządzane przez serwer. RESTful API, gdy jest wykonane prawidłowo, jest bezstanowe (co oznacza, że ​​nie ma stanu serwera, którym trzeba zarządzać), dlatego skalowalność może rosnąć poziomo (co jest tańsze) niż pionowo .

Archimedes Trajano
źródło
2

Czy chcę aktualizacje z serwera?

  • Tak: Socket.io
  • Bez odpoczynku

Wady Socket.io to:

  • Skalowalność: WebSockets wymagają otwartych połączeń i znacznie różniącej się konfiguracji operacji w celu skalowania sieci.
  • Learnin: Nie mam nieograniczonego czasu na naukę. Trzeba coś zrobić!

Nadal będę używać Socket.io w moim projekcie, ale nie w przypadku podstawowych formularzy internetowych, które REST będzie dobrze działać.

Michael Cole
źródło
1

Transporty oparte na protokołach WebSockets (lub długich odpytywaniach) służą głównie do (prawie) komunikacji w czasie rzeczywistym między serwerem a klientem. Chociaż istnieje wiele scenariuszy, w których wymagane są tego rodzaju transporty, takie jak czat lub jakieś źródła danych w czasie rzeczywistym lub inne rzeczy, nie wszystkie części niektórych aplikacji internetowych muszą być koniecznie połączone dwukierunkowo z serwerem.

REST jest architekturą opartą na zasobach, która jest dobrze rozumiana i oferuje własne korzyści w porównaniu z innymi architekturami. WebSockets skłaniają się bardziej do strumieni / źródeł danych w czasie rzeczywistym, co wymagałoby stworzenia pewnego rodzaju logiki opartej na serwerze w celu ustalenia priorytetów lub rozróżnienia między zasobami i kanałami (na wypadek, gdybyś nie chciał używać REST).

Zakładam, że w przyszłości będzie więcej struktur zorientowanych na WebSockets, takich jak socketstream, kiedy ten transport będzie bardziej rozpowszechniony i lepiej zrozumiany / udokumentowany w postaci dostarczania agnostycznego typu / formy danych. Myślę jednak, że nie oznacza to, że zastąpiłby / powinien zastąpić REST tylko dlatego, że oferuje funkcjonalność, która niekoniecznie jest wymagana w wielu przypadkach użycia i scenariuszach.

yojimbo87
źródło
0

Chciałbym zwrócić uwagę na ten wpis na blogu, który należy do mnie, najlepszą odpowiedź na to pytanie.

Krótko mówiąc, TAK

Post zawiera wszystkie najlepsze praktyki dla tego rodzaju API.

David D.
źródło
-1

To nie jest dobry pomysł. Standard nie jest jeszcze sfinalizowany, obsługa różni się w różnych przeglądarkach itp. Jeśli chcesz to zrobić teraz, będziesz musiał wrócić do flashowania lub długiego odpytywania itp. W przyszłości prawdopodobnie nadal nie będzie Ma to sens, ponieważ serwer musi obsługiwać pozostawianie otwartych połączeń dla każdego użytkownika. Zamiast tego większość serwerów internetowych jest zaprojektowana tak, aby szybko odpowiadać na żądania i zamykać je tak szybko, jak to możliwe. Do licha, nawet system operacyjny musiałby być dostrojony do obsługi dużej liczby jednoczesnych połączeń (każde połączenie zużywa więcej efemerycznych portów i pamięci). Trzymaj się REST dla jak największej części witryny.

zeekay
źródło
Tak, większość usług internetowych wyróżnia się protokołem HTTP. Ale node.js nie jest serwerem WWW, to biblioteka io. Potrafi dobrze wykonać TCP. Zasadniczo chodzi o to, czy możemy projektować strony internetowe tak, aby używały protokołu TCP zamiast HTTP.
Raynos,
Obowiązują te same ograniczenia, nadal zabraknie Ci efemerycznych portów / pamięci, nadal ograniczy to liczbę osób, które możesz obsłużyć jednocześnie, i będzie niepotrzebnie obciążać system.
zeekay
tak, istnieje limit, ale nie sądzę, że to taka wielka sprawa, jeśli nie utworzysz nowego wątku na połączenie.
Raynos,
Mam już gniazdo dla każdego użytkownika. globalny czat + kanał aktualności.
Harry,
1
Myślę, że w 2011 roku była to świetna odpowiedź. - Więc widzę, skąd pochodzisz. Ale w 2019 roku websockets dojrzał.
bvdb