Oddzielny serwer REST JSON API i klient? [Zamknięte]

371

Zaraz stworzę kilka aplikacji internetowych od zera. (Zobacz http://50pop.com/code w celu omówienia.) Chciałbym, aby można było uzyskać do nich dostęp z wielu różnych klientów: witryn front-end, aplikacji na smartfony, usług web backend itp. Więc naprawdę chcę JSON REST API dla każdego z nich.

Wolę też pracować nad back-endem, więc marzę o tym, aby skupić się wyłącznie na interfejsie API i zatrudnić kogoś innego do stworzenia interfejsu użytkownika, czy to strony internetowej, iPhone'a, Androida czy innej aplikacji.

Pomóż mi zdecydować, które podejście powinienem zastosować:

RAZEM W SZYNACH

Stwórz bardzo standardową aplikację internetową Rails. W kontrolerze wykonaj przełącznik respond_with, aby obsługiwać JSON lub HTML. Odpowiedź JSON jest wtedy moim API.

Pro: Wiele precedensów. Świetne standardy i wiele przykładów robienia rzeczy w ten sposób.

Przeciw: niekoniecznie chcę, aby interfejs API był taki sam jak aplikacja internetowa. Nie podoba mi się, jeśli / następnie odpowiedz z przełączaniem. Mieszanie dwóch bardzo różnych rzeczy (interfejs użytkownika + interfejs API).

SERWER REST + JAVASCRIPT-CIĘŻKI KLIENT

Utwórz serwer API REST tylko do JSON. Użyj Backbone lub Ember.js dla JavaScript po stronie klienta, aby uzyskać bezpośredni dostęp do API, wyświetlając szablony w przeglądarce.

Pro: Uwielbiam oddzielanie API i klienta. Sprytni ludzie twierdzą, że jest to dobra droga. Świetny w teorii. Wydaje się najnowocześniejszy i ekscytujący.

Con: Nie ma precedensu. Niewiele przykładów tego zostało zrobionych dobrze. Przykłady publiczne (twitter.com) są powolne i nawet odchodzą od tego podejścia.

SERWER REST + KLIENT HTML SERWERA

Utwórz serwer API REST tylko do JSON. Stwórz podstawowego klienta strony HTML, który uzyskuje dostęp tylko do interfejsu API REST. Mniej JavaScript po stronie klienta.

Pro: Uwielbiam oddzielanie API i klienta. Ale obsługa zwykłego HTML5 jest dość niezawodna i nie wymaga dużego klienta.

Con: Nie ma precedensu. Niewiele przykładów tego zostało zrobionych dobrze. Ramy również tego nie obsługują. Nie jestem pewien, jak do tego podejść.

Szczególnie szukam porady z doświadczenia, nie tylko w teorii.

sivers
źródło
50
generalnie wolimy, aby spekulacyjne, koncepcyjne pytania na tablicy trafiały na programmers.stackexchange.com, podczas gdy pytania na temat przepełnienia stosu powinny zawierać rzeczywisty kod źródłowy w 99% przypadków. Ale to dobrze zadane pytanie i uwielbiam twoją pracę, więc na razie może spaść w szarą strefę.
Jeff Atwood
2
Czy ktoś ma jakieś przykłady / źródła (aby zrozumieć ich powody) dla tych, którzy odchodzą od opcji 2?
Víctor López García
12
@frntk Pierwotnym powodem, dla którego wiele firm (takich jak Twitter) robiło Javascript, było to, że uważali, że będzie to szybsze. Teraz zdają sobie sprawę, że tak naprawdę jest wolniej. Zobacz engineering.twitter.com/2012/05/... i openmymind.net/2012/5/30/Client-Side-vs-Server-Side-Rendering
Moshe Katz
1
Przeczytaj komentarze w linkach powyżej. Wiele założeń tego artykułu obala logika i doświadczenie.
Ricalsin,
1
W dzisiejszych czasach chciałbyś utworzyć backend JSON API zgodny ze specyfikacją jsonapi.org ... :)
Askar,

Odpowiedzi:

136

W Boundless pogłębiliśmy opcję 2 i udostępniliśmy ją tysiącom studentów. Nasz serwer to JSON REST API (Scala + MongoDB), a cały nasz kod klienta jest obsługiwany bezpośrednio z CloudFront (tj. Www.boundless.com to tylko alias dla CloudFront).

Plusy:

  • Najnowocześniejsze / ekscytujące
  • Dużo pieniędzy za grosze: API daje podstawę dla własnego klienta internetowego, klientów mobilnych, dostępu stron trzecich itp.
  • niezwykle szybkie ładowanie strony / przejścia stron

Cons:

  • Nie jest przyjazny dla SEO / gotowy bez większej ilości pracy.
  • Wymaga ludzi z czołowych stron internetowych, którzy są gotowi poradzić sobie z rzeczywistością witryny, która jest w 70% javascript i co to oznacza.

Myślę, że to przyszłość wszystkich aplikacji internetowych.

Kilka przemyśleń na temat frontonu internetowego (w którym cała ta nowość / wyzwanie ma tę architekturę):

  • CoffeeScript. Znacznie łatwiej jest stworzyć kod wysokiej jakości.
  • Kręgosłup. Świetny sposób na uporządkowanie logiki i aktywną społeczność.
  • HAMLC. Szablony Haml + CoffeeScript => JS.
  • SASS

Stworzyliśmy uprząż dla naszego front-endowego oprogramowania o nazwie „Spar” (Rocketship z pojedynczą stroną aplikacji), która jest efektywnym potokiem zasobów od Railsa dostosowanym do tworzenia aplikacji na jednej stronie. W ciągu najbliższych kilku tygodni będziemy udostępniać open source na naszej stronie github , wraz z postem na blogu wyjaśniającym, jak z niego korzystać i ogólną architekturę bardziej szczegółowo.

AKTUALIZACJA:

Jeśli chodzi o obawy ludzi związane z kręgosłupem, myślę, że są one przecenione. Kręgosłup jest o wiele bardziej zasadą organizacyjną niż głębokimi ramami. Sama strona Twittera to gigantyczna bestia Javascript, która obejmuje każdy przypadek milionów użytkowników i starszych przeglądarek, jednocześnie ładując tweety w czasie rzeczywistym, zbierając śmieci, wyświetlając dużo multimediów itp. Ze wszystkich „czystych” stron js widać, że Twitter jest dziwny. Dostarczono wiele imponująco skomplikowanych aplikacji za pośrednictwem JS, które radzą sobie bardzo dobrze.

A wybór architektury zależy całkowicie od twoich celów. Jeśli szukasz najszybszego sposobu obsługi wielu klientów i masz dostęp do dobrych talentów front-end, inwestowanie w samodzielny interfejs API to świetny sposób.

Aaron
źródło
1
Drobna kwestia do dodania: Chociaż zbudowałem tylko opcję nr 1, znam wielu programistów aplikacji mobilnych, którzy zaczynają używać parse.com jako zaplecza, aby umożliwić szybką ścieżkę do nr 2.
Rhb123
Rzeczy takie jak Parse i Kinvey są bardzo interesujące, nie mogę powiedzieć, że miałem jeszcze okazję grać w nich. Zależy, czy twoja wartość znajduje się z przodu czy z tyłu stosu, jak sądzę
Aaron
Używam tego samego podejścia do spinendów dla frontendu.
Nicolas Goy,
Jak radzisz sobie z jedną domeną z dwiema osobnymi aplikacjami? Na przykład. Mam witrynę www.mysite.com i chcę udostępnić publiczny interfejs API i udostępnić interfejs użytkownika pod tym adresem URL. Zgodnie z zasadami REST dostęp do mysite.com/product/24 z przeglądarki internetowej powinien zwrócić stronę HTML, patrząc na nagłówek HTTP Accept, a GET z JSON w nagłówku Accept na mysite.com/product/24 powinien zwrócić JSON .
Erich,
Jak poradziłaby sobie z tym AngularJS?
Ankan-Zerob
48

Bardzo dobrze zapytany. +1. Na pewno jest to dla mnie przydatne odniesienie w przyszłości. Również @Aaron i inni wnieśli wartość dodaną do dyskusji. Podobnie jak Ruby, to pytanie dotyczy w równym stopniu innych środowisk programistycznych.

Użyłem dwóch pierwszych opcji. Pierwsza do wielu aplikacji i druga do mojego projektu open source Cowoop

opcja 1

Ten jest bez wątpienia najbardziej popularny. Ale uważam, że implementacja jest bardzo podobna do http. Początkowy kod każdego interfejsu API obsługuje obiekt żądania. Więc kod API to coś więcej niż czysty kod ruby ​​/ python / inny język.

Opcja 2

Zawsze to lubiłem.

Ta opcja oznacza również, że HTML nie jest generowany w środowisku wykonawczym na serwerze. W ten sposób opcja 2 różni się od opcji 3. Ale są budowane jako statyczny HTML za pomocą skryptu kompilacji. Po załadowaniu po stronie klienta HTML wywoływałby serwer API jako klient API JS.

  • Rozdzielenie obaw jest wielką zaletą. I bardzo, jak lubisz (i moje), eksperci od backendów implementują interfejsy API backend, testuj je łatwo jak zwykły kod języka, nie martwiąc się o kod żądania frameworku / http.

  • To naprawdę nie jest tak trudne, jak się wydaje po stronie frontendu. Czy wywołania API i dane wynikowe (głównie json) są dostępne dla szablonu po stronie klienta lub MVC.

  • Mniej przetwarzania po stronie serwera. Oznacza to, że możesz wybrać sprzęt / tańszy serwer.

  • Łatwiej testować warstwy niezależnie, łatwiej generować dokumenty API.

Ma pewne wady.

  • Wielu programistów uważa to za zbyt skomplikowane i trudne do zrozumienia. Są więc szanse, że architektura może zostać skrytykowana.

  • i18n / l10n jest trudny. Ponieważ zasadniczo generowany jest HTML, czas kompilacji jest statyczny, potrzeba wielu kompilacji na obsługiwany język (co niekoniecznie jest złą rzeczą). Ale nawet z tym możesz mieć skrzynie narożne wokół l10n / i18n i musisz być ostrożny.

Opcja 3

Kodowanie zaplecza w tym przypadku musi być takie samo jak druga opcja. Tutaj również ma zastosowanie większość punktów za opcję 2.

Strony internetowe są renderowane przy użyciu szablonów po stronie serwera. Dzięki temu i18n / l10n jest znacznie łatwiejszy dzięki bardziej ustalonym / akceptowanym technikom. Może być o jedno połączenie mniej HTTP dla pewnego niezbędnego kontekstu potrzebnego do renderowania strony, takiego jak użytkownik, język, waluta itp. Tak więc przetwarzanie po stronie serwera jest zwiększone z renderowaniem, ale być może kompensowane przez mniej połączeń HTTP do serwera API.

Teraz, gdy strony są renderowane na serwerze, frontend jest teraz bardziej powiązany ze środowiskiem programistycznym. W przypadku wielu aplikacji może to nawet nie być brane pod uwagę.

Sprawa na Twitterze

Jak rozumiem, Twitter może początkowo renderować strony na serwerze, ale w przypadku aktualizacji stron nadal ma pewne wywołania API i szablony po stronie klienta do manipulowania DOM. W takim przypadku masz do utrzymania podwójne szablony, co zwiększa pewne koszty i złożoność. Nie każdy może sobie pozwolić na tę opcję, w przeciwieństwie do Twittera.

Nasz projekt Stack

Zdarza mi się używać Pythona. Używam JsonRPC 2.0 zamiast REST. Sugeruję REST, chociaż podoba mi się pomysł JsonRPC z różnych powodów. Korzystam z poniższych bibliotek. Ktoś rozważający opcję 2/3 może uznać ją za przydatną.

  • Serwer API: Python Szybka mikrocząsteczka internetowa - Flask
  • Serwer frontonu: Nginx
  • Po stronie klienta MVC: Knockout.js
  • Inne odpowiednie narzędzia / biblioteki:

Moje wnioski i rekomendacje

Opcja 3 !.

Wszystko powiedziawszy, z powodzeniem wykorzystałem opcję 2, ale teraz przechodzę do opcji 3 dla pewnej uproszczenia. Generowanie statycznych stron HTML za pomocą skryptu kompilacji i serwowanie ich za pomocą jednego z ultraszybkich serwerów specjalizujących się w obsłudze statycznych stron jest bardzo kuszące (Opcja 2).

Shekhar
źródło
Podoba mi się również opcja 2, ale opcja 3 ma wiele zalet, których nie możemy się pozbyć. Próbuję znaleźć rozwiązanie hydrid łączące oba opt2 + opt3, ale doprowadzi to do bólu głowy, takiego jak Twitter.
Blue Smith
Uwielbiam opcję 3 i staram się jej użyć, jeśli chodzi o bieżący projekt. Jakieś np. Repozytorium git, na które możesz wskazać pomoc?
AmaChefe,
@AmaChefe Chciałbym. W obecnym projekcie, w którym SEO ma kluczowe znaczenie, korzystamy z opcji 3. Kod nie jest jednak oprogramowaniem typu open source. Używamy flask + jinja2 i knockout / reag.js.
Shekhar,
28

Zdecydowaliśmy się na numer 2 podczas tworzenia miernika.es. Pracowałem nad interfejsem API (ruby, sinatra itp.), A mój partner biznesowy, Steve Smith, pracował nad interfejsem (klient javascript).

Plusy:

  1. Poruszaj się szybko równolegle. Gdybym pracował przed Steve'em, mógłbym nadal tworzyć interfejsy API dla nowych funkcji. Gdyby przede mną pracował, mógłby bardzo łatwo sfałszować interfejs API i zbudować interfejs użytkownika.

  2. API za darmo. Otwarty dostęp do danych w aplikacji szybko staje się standardową funkcją. Jeśli zaczynasz od interfejsu API od podstaw, otrzymasz to za darmo.

  3. Czysta separacja. Lepiej jest myśleć o aplikacji jako interfejsie API z klientami. Oczywiście, pierwszym i najważniejszym klientem może być internetowy, ale umożliwia łatwe tworzenie innych klientów (iPhone, Android).

Cons:

  1. Kompatybilność wsteczna. Jest to bardziej związane z interfejsem API niż z bezpośrednim pytaniem, ale gdy interfejs API jest już dostępny, nie można go po prostu złamać lub wszystkich dwóch klientów. Nie oznacza to, że musisz poruszać się wolniej, ale oznacza to, że często musisz sprawić, by dwie rzeczy działały jednocześnie. Dodawanie do interfejsu API lub nowych pól jest w porządku, ale zmiana / usuwanie nie powinna odbywać się bez wersji.

Nie mogę teraz myśleć o żadnych wadach.

Wniosek: klient API + JS jest dobrym rozwiązaniem, jeśli planujesz wydanie API.

PS Polecam również pełną dokumentację interfejsu API przed jego wydaniem. Proces dokumentowania API Gaug.es naprawdę pomógł nam imp

http://get.gaug.es/documentation/api/

John Nunemaker
źródło
13
Czy mogę zapytać, w jaki sposób uwierzytelniasz interfejs WWW za pomocą interfejsu API REST? Widziałem, że potrzebujesz klucza API do komunikacji z API, który jest uzyskiwany po zalogowaniu się do swojego profilu użytkownika. Ale w jaki sposób klient sieciowy otrzymuje klucz API, jeśli wiesz, co mam na myśli?
Sebastian Wramba
@SebastianWramba Jest już późno, ale odkąd twój komentarz otrzymał 12 pozytywnych opinii ... Chciałbym spojrzeć na coś w rodzaju autoryzacji hasła OAuth2 . Jeśli jesteś twórcą aplikacji wywołującej API, jest to prawdopodobnie podejście, które prawdopodobnie nie używa klucza API. Jeśli jest to aplikacja innej firmy, musisz zalogować się do swojej witryny, aby uzyskać klucz API, a następnie użytkownik używa tego klucza (i wszelkich innych niezbędnych poświadczeń), aby uzyskać dostęp do interfejsu API za pośrednictwem swojej aplikacji, strony internetowej itp.
GreeKatrina
10

Wolę iść drogą nr 2 i nr 3. Głównie dlatego, że nr 1 narusza separację problemów i przenika różne rzeczy. W końcu okaże się, że musisz mieć punkt końcowy interfejsu API, który nie ma pasującej strony HTML / etc, i będziesz w potoku z przeplatanymi punktami końcowymi HTML i JSON w tej samej bazie kodu. Zmienia się w dziwaczny bałagan, nawet jeśli jest to MVP, w końcu będziesz musiał go ponownie napisać, ponieważ jest tak bałaganiarski, że nawet nie warto go ratować.

Korzystanie z # 2 lub # 3 pozwala całkowicie mieć interfejs API, który działa tak samo (w przeważającej części) niezależnie. Zapewnia to dużą elastyczność. Nie jestem jeszcze w 100% sprzedawany na Backbone / ember / cokolwiek / itd. Js. Myślę, że jest świetny, ale jak widzimy na Twitterze, nie jest to optymalne. ALE ... Twitter jest także wielką bestią firmy i ma setki milionów użytkowników. Tak więc każda poprawa może mieć ogromny wpływ na wyniki finansowe w różnych obszarach różnych jednostek biznesowych. Myślę, że decyzja zależy nie tylko od prędkości i nie pozwalają nam na to. Ale to tylko moja opinia. Jednak nie dyskontuję kręgosłupa i jego konkurentów. Te aplikacje są świetne w użyciu, są bardzo czyste i są bardzo responsywne (w przeważającej części).

Trzecia opcja ma również pewien ważny urok. Tutaj przestrzegałbym zasady Pareto (zasada 80/20) i wyświetlał 20% twojego głównego znacznika (lub odwrotnie) na serwerze, a następnie ładnego klienta JS (szkielet / etc) uruchomił resztę . Być może nie komunikujesz się w 100% z interfejsem API REST za pośrednictwem klienta JS, ale w razie potrzeby wykonasz trochę pracy, aby poprawić wrażenia użytkownika.

Myślę, że jest to jeden z tych „problemów”, a odpowiedź brzmi „zależy” od tego, co robisz, komu służysz i jakiego rodzaju doświadczenia chcesz, aby otrzymali. Biorąc pod uwagę, że myślę, że możesz zdecydować między 2 lub 3 lub hybrydą z nich.

Donn Felker
źródło
+1 do hybrydy 2 i 3
Ujjwal Ojha
7

Obecnie pracuję nad konwersją ogromnego CMS z opcji 1 na opcję 3 i idzie dobrze. Zdecydowaliśmy się renderować znaczniki po stronie serwera, ponieważ SEO to dla nas wielka sprawa i chcemy, aby witryny działały dobrze na telefonach komórkowych.

Używam node.js do zaplecza klienta i kilku modułów, które mi w tym pomogą. Jestem nieco na wczesnym etapie procesu, ale podstawa jest już ustalona i chodzi o to, aby przejrzeć dane i upewnić się, że wszystko jest poprawnie renderowane. Oto, czego używam:

  • Ekspresowe założenie aplikacji.
    (https://github.com/visionmedia/express)
  • Żądanie pobrania danych.
    (https://github.com/mikeal/request)
  • Szablony podkreślenia, które są renderowane po stronie serwera. Używam ich ponownie na kliencie.
    (https://github.com/documentcloud/underscore)
  • UTML otacza szablony podkreślenia, aby działały z Express.
    (https://github.com/mikefrey/utml)
  • Upfront zbiera szablony i pozwala wybrać, które zostaną wysłane do klienta.
    (https://github.com/mrDarcyMurphy/upfront)
  • Express Expose przekazuje pobrane dane, niektóre moduły i szablony do interfejsu.
    (https://github.com/visionmedia/express-expose)
  • Szkielet tworzy modele i widoki w interfejsie użytkownika po połknięciu przekazanych danych.
    (https://github.com/documentcloud/backbone)

To jest rdzeń stosu. Pomocne są też inne moduły:

  • fleck (https // github.com / trek / fleck)
  • moment (https // github.com / timrwood / moment)
  • rysik (https // github.com / LearnBoost / rysus)
  • smoosh (https // github.com / fat / smoosh)
    … chociaż patrzę w chrząknięcie (https // github.com / cowboy / grunt)
  • śledzenie konsoli (//github.com/LearnBoost/console-trace).

Nie, nie używam coffeescript.

Ta opcja działa dla mnie naprawdę dobrze. Modele na zapleczu nie istnieją, ponieważ dane, które otrzymujemy z API są dobrze ustrukturyzowane i przekazuję je dosłownie do interfejsu. Jedynym wyjątkiem jest nasz model układu, w którym dodaję pojedynczy atrybut, który sprawia, że ​​renderowanie jest mądrzejsze i lżejsze. Nie użyłem do tego żadnej fantazyjnej biblioteki modeli, tylko funkcję, która dodaje to, czego potrzebuję przy inicjalizacji i zwraca się.

(przepraszam za dziwne linki, jestem zbyt n00b za przepełnienie stosu, aby pozwolić mi opublikować tyle)

Darcy Murphy
źródło
1
Czyli renderujesz znaczniki po stronie serwera, ale nadal dajesz szablony klientowi i używasz szkieletu?
Shannon,
7

Używamy następującego wariantu nr 3: Utwórz serwer API REST tylko dla JSON. Stwórz serwer strony HTML. Serwer WWW HTML nie jest, jak w twoim wariancie, klientem serwera API REST. Zamiast tego są rówieśnikami. Niedaleko pod powierzchnią znajduje się wewnętrzny interfejs API zapewniający funkcjonalność potrzebną obu serwerom.

Nie znamy żadnego precedensu, więc jest to rodzaj eksperymentu. Do tej pory (wkrótce wejdzie w wersję beta) działało całkiem dobrze.

Thomas Becker
źródło
Myślę o tej opcji, aby uniknąć problemów związanych z byciem właściwym klientem API, takich jak uwierzytelnianie. Chciałbym dowiedzieć się więcej o tym, jak ustrukturyzowałeś całość i jak zarządzasz separacją i komunikacją między trzema różnymi częściami. Czy mogę coś przeczytać? Dzięki!
MartinodF,
2
@MartinodF Hostujemy na Google App Engine, który ogranicza się do Java lub Python. Chciałem używać Pythona, ale zostałem zmuszony do pracy w Javie, ponieważ łamiemy liczby (nie możemy rozszerzyć Py z C / C ++ na GAE). Jako ramy prezentacji wybraliśmy Stripes (Stripes, not Struts, not Spring). Bardzo się z tego cieszę. Cała sprawa to jedna aplikacja Java na GAE. Podstawowa funkcjonalność jest wbudowana w kilka pakietów Java i ujawniona w wewnętrznym interfejsie API. Istnieje serwlet, który zapewnia usługę JSON REST, a drugi jest skonfigurowany jako aplikacja internetowa Stripes. Ponieważ jest to jedna aplikacja GAE Java, komunikacja jest banalna.
Thomas Becker,
Dzięki za wgląd, jest to bardzo przydatne!
MartinodF
7

Zwykle wybieram drugą opcję, używając Railsów do zbudowania API i szkieletu dla JS. Możesz nawet uzyskać panel administracyjny za darmo za pomocą ActiveAdmin . Wysłałem dziesiątki aplikacji mobilnych z tego rodzaju zapleczem. Jednak w dużej mierze zależy to, czy Twoja aplikacja jest interaktywna, czy nie.

Zrobiłem prezentację na temat tego podejścia podczas ostatniego RubyDay.it : http://www.slideshare.net/matteocollina/enter-the-app-era-with-ruby-on-rails-rubyday

W przypadku trzeciej opcji, aby uzyskać odpowiedź na drugą, możesz wypróbować pajax, tak jak robi to Github.

Matteo Collina
źródło
6

Mam około 2 miesięcy na 3-miesięczny projekt, który przyjmuje drugie podejście, które tutaj nakreśliłeś. Używamy strony RESTful API po stronie backbone.js. Handlebars.js zarządza szablonami, a jQuery obsługuje manipulacje AJAX i DOM. W przypadku starszych przeglądarek i pająków wyszukiwania wróciliśmy do renderowania po stronie serwera, ale używamy tych samych szablonów HTML, co nakładka Handlebars przy użyciu Mozilla Rhino.

Wybraliśmy to podejście z wielu różnych powodów, ale jesteśmy świadomi, że jest to trochę ryzykowne, ponieważ nie zostało jeszcze udowodnione na szeroką skalę. Wszystko to samo, do tej pory wszystko szło gładko.

Do tej pory pracowaliśmy tylko z jednym interfejsem API, ale w następnej fazie projektu będziemy pracować z drugim interfejsem API. Pierwszy dotyczy dużych ilości danych, a drugi działa bardziej jak CMS za pośrednictwem interfejsu API.

Zależność tych dwóch części projektu od siebie całkowicie niezależna była kluczowym czynnikiem przy wyborze tej infrastruktury. Jeśli szukasz architektury do łączenia różnych niezależnych zasobów bez żadnych zależności, warto przyjrzeć się temu podejściu.

Obawiam się, że nie jestem facetem Ruby, więc nie mogę komentować innych podejść. Czasami można zaryzykować. Innym razem lepiej jest grać bezpiecznie. Będziesz się winien w zależności od rodzaju projektu.

Powodzenia w wyborze tutaj. Chciałbym zobaczyć, co udostępniają również inni.

Iarfhlaith Kelly
źródło
1
Wykrywasz więc, czy żądanie pochodzi od bota wyszukiwania, i jeśli tak, to wyświetlasz wstępnie renderowany HTML, a jeśli nie, to szablony JS +?
Shannon,
4

Podoba mi się # 3, gdy moja witryna nie będzie w 100% implementacją CRUD moich danych. Co się jeszcze nie wydarzyło.

Wolę sinatrę i po prostu podzielę aplikację na kilka różnych aplikacji do szaf w różnych celach. Zrobię specyficzną dla API aplikację stelażową, która obejmie to, czego potrzebuję do API. Być może aplikacja użytkownika, która zaprezentuje moją stronę. Czasami ta wersja wysyła zapytanie do API w razie potrzeby, ale zwykle dotyczy tylko strony HTML.

Nie martwię się o to i po prostu wykonuję kwerendę warstwy utrwalającej ze strony użytkownika, jeśli jej potrzebuję. Nie przejmuję się zbytnio tworzeniem całkowitej separacji, ponieważ zwykle służą one różnym celom.

Oto bardzo prosty przykład korzystania z wielu aplikacji w szafie. Dodałem tam szybki przykład jquery, aby zobaczyć, jak uderza on w aplikację API. Możesz zobaczyć, jak łatwo może być z sinatrą i montażem wielu aplikacji do szaf w różnych celach.

https://github.com/dusty/multi-rack-app-app

Zakurzony
źródło
1

Kilka świetnych odpowiedzi tutaj - zdecydowanie polecam # 2 lub # 3 - separacja jest dobra koncepcyjnie, ale także w praktyce.

Trudno jest przewidzieć takie rzeczy, jak wzorce obciążenia i ruchu w interfejsie API, a klienci, którzy niezależnie obsługują interfejs API, mają łatwiejszy czas udostępniania i skalowania. Jeśli musisz to zrobić w połączeniu z ludzkimi wzorcami dostępu do sieci, jest to mniej łatwe. Również użycie interfejsu API może skończyć się skalowaniem znacznie szybciej niż klienta WWW, a następnie możesz zobaczyć, gdzie skierować swoje wysiłki.

Pomiędzy nr 2 # 3 to naprawdę zależy od twoich celów - Zgadzam się, że # 2 to prawdopodobnie przyszłość aplikacji internetowych - ale może chcesz czegoś prostszego, jeśli ten kanał będzie tylko jednym z wielu!

Steve
źródło
1

W przypadku strony atyourservice.com.cy używamy szablonów renderowanych po stronie serwera, szczególnie do pokrycia części se. I używanie interfejsu API do interakcji po załadowaniu strony. Ponieważ naszym frameworkiem jest MVC, wszystkie funkcje kontrolera są zduplikowane do wyjścia json i html. Szablony są czyste i otrzymują tylko obiekt. Można to przekształcić w szablony js w kilka sekund. Zawsze utrzymujemy szablony po stronie serwera i po prostu konwertujemy na js na żądanie.

xatzistnr
źródło
1

Renderowanie izomorficzne i stopniowe ulepszanie. Myślę, że właśnie do tego zmierzałeś w opcji trzeciej.

renderowanie izomorficzne oznacza używanie tego samego szablonu do generowania znaczników po stronie serwera, jak w kodzie klienta. Wybierz język szablonów z dobrymi implementacjami po stronie serwera i klienta. Utwórz w pełni upieczony HTML dla swoich użytkowników i prześlij go dalej. Użyj również buforowania.

progresywne doskonalenie oznacza rozpoczęcie wykonywania po stronie klienta oraz renderowania i nasłuchiwania zdarzeń po pobraniu wszystkich zasobów i określeniu możliwości klienta. Wracając do funkcjonalnej funkcjonalności bez skryptów klienckich, o ile to możliwe, w celu zapewnienia dostępności i kompatybilności wstecznej.

Tak, oczywiście napisz samodzielny interfejs json dla tej funkcji aplikacji. Ale nie idź tak daleko, że piszesz json api dla rzeczy, które działają dobrze jako statyczne dokumenty HTML.

sirtimbly
źródło
1

Serwer REST + klient obciążony JavaScript był zasadą, której przestrzegałem w mojej ostatniej pracy.

Serwer REST został zaimplementowany w node.js + Express + MongoDB (bardzo dobra wydajność zapisu) + Mongoose ODM (świetny do modelowania danych, w tym sprawdzania poprawności) + CoffeeScript (teraz zamiast tego wybrałbym ES2015), który działał dobrze dla mnie. Node.js może być stosunkowo młody w porównaniu do innych możliwych technologii po stronie serwera, ale umożliwił mi napisanie solidnego API ze zintegrowanymi płatnościami.

Użyłem Ember.js jako struktury JavaScript i większość logiki aplikacji została wykonana w przeglądarce. Użyłem SASS (szczególnie SCSS) do wstępnego przetwarzania CSS.

Ember to dojrzałe środowisko wspierane przez silną społeczność. Jest to bardzo potężny framework z dużą ilością ostatnio wykonywanych prac związanych z wydajnością, jak zupełnie nowy silnik renderujący Glimmer (zainspirowany przez React).

Zespół Ember Core opracowuje FastBoot , który umożliwia wykonywanie logiki Ember JavaScript po stronie serwera (w szczególności node.js) i wysyłanie do użytkownika wstępnie renderowanego kodu HTML aplikacji (który normalnie byłby uruchamiany w przeglądarce). Jest to świetne dla SEO i doświadczenia użytkownika, ponieważ nie czeka tak długo na wyświetlenie strony.

Ember CLI to świetne narzędzie, które pomaga uporządkować kod i dobrze się skalowało wraz z rosnącą bazą kodu. Ember ma również własny ekosystem dodatków i możesz wybierać spośród wielu dodatków Ember . Możesz łatwo pobrać Bootstrap (w moim przypadku) lub Foundation i dodać go do swojej aplikacji.

Aby nie obsługiwać wszystkiego za pośrednictwem Express, zdecydowałem się użyć nginx do wyświetlania obrazów i klienta obciążonego JavaScript. W moim przypadku pomocne było użycie serwera proxy nginx:

upstream app_appName.com {
  # replace 0.0.0.0 with your IP address and 1000 with your port of node HTTP server
  server 0.0.0.0:1000;
  keepalive 8;
}

server {
  listen 80 default_server;
  listen [::]:80 default_server ipv6only=on;

  client_max_body_size 32M;

  access_log  /var/log/nginx/appName.access.log;
  error_log  /var/log/nginx/appName.error.log;

  server_name appName.com appName;

  location / {
     # frontend assets path
     root /var/www/html;
     index index.html;

     # to handle Ember routing
     try_files $uri $uri/ /index.html?/$request_uri;
  }

  location /i/ {
    alias /var/i/img/;
  }

  location /api/v1/ {
    proxy_pass  http://app_appName.com;

    proxy_next_upstream error timeout invalid_header http_500 http_502
http_503 http_504;
    proxy_redirect off;
    proxy_buffering off;
    proxy_set_header        Host            $host;
    proxy_set_header        X-Real-IP       $remote_addr;
    proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
  }
}

Pro: Uwielbiam oddzielanie API i klienta. Sprytni ludzie twierdzą, że jest to dobra droga. Świetny w teorii. Wydaje się najnowocześniejszy i ekscytujący.

Mogę powiedzieć, że jest również świetny w praktyce. Kolejną zaletą oddzielenia interfejsu API REST jest to, że można go później użyć ponownie w innych aplikacjach. W idealnym świecie powinieneś móc korzystać z tego samego interfejsu API REST nie tylko na stronie internetowej, ale także w aplikacjach mobilnych, jeśli zdecydujesz się go napisać.

Con: Nie ma precedensu. Niewiele przykładów tego zostało zrobionych dobrze. Przykłady publiczne (twitter.com) są powolne i nawet odchodzą od tego podejścia.

Teraz sprawy wyglądają inaczej. Istnieje wiele przykładów robienia API REST + wielu klientów go używających.

Daniel Kmak
źródło
1

Zdecydowałem się na architekturę Opcji # 2 dla Infiniform , ponieważ zapewnia ona świetny sposób na oddzielenie interfejsu użytkownika od logiki biznesowej.

Zaletą tego jest to, że serwery API można skalować niezależnie od serwerów WWW. Jeśli masz wielu klientów, witryny nie będą musiały być skalowane w takim samym stopniu jak serwery sieciowe, ponieważ niektórzy klienci będą musieli korzystać z telefonu / tabletu lub komputera.

Takie podejście zapewnia również dobrą podstawę do otwarcia interfejsu API dla użytkowników, zwłaszcza jeśli używasz własnego interfejsu API w celu zapewnienia wszystkich funkcji witryny.

Karl Gjertsen
źródło
1

Bardzo miłe pytanie i jestem zaskoczony, ponieważ myślałem, że jest to obecnie bardzo częste zadanie, ponieważ będę miał mnóstwo zasobów na ten problem, jednak okazało się to nieprawdą.

Moje przemyślenia są następujące: - Stwórz moduł, który ma wspólną logikę między kontrolerami API i kontrolerami HTML bez zwracania json lub renderowania HTML, i dołącz ten moduł zarówno do kontrolera HTML, jak i kontrolera API, a następnie rób co chcesz, na przykład :

module WebAndAPICommon
    module Products

        def index
            @products = # do some logic here that will set @products variable
        end

    end
end


class ProductsController < ApplicationController
    # default products controlelr, for rendering HMTL pages 
    include WebAndAPICommon

    def index
        super
    end

end



module API
    class ProductsController
        include WebAndAPICommon

        def index
            super
            render json: @products
        end

    end
end

źródło
0

Poszedłem do hybrydowego podejścia, w którym korzystamy z Sinatry jako bazy, ActiveRecord / Postgress itp. W celu obsługi tras stron (wąskie szablony) ujawniają API REST, którego może używać aplikacja internetowa. We wczesnym okresie programowania rzeczy takie jak wypełnianie wybranych opcji są wykonywane za pomocą pomocników renderujących w cienki szablon, ale gdy zbliżamy się do produkcji, zostaje to zamienione na wywołanie AJAX do interfejsu API REST, gdy zaczynamy bardziej dbać o szybkość ładowania strony i tak dalej.

Rzeczy łatwe do renderowania w Slim są obsługiwane w ten sposób, a rzeczy (wypełnianie formularzy, odbieranie danych POST formularza z jQuery.Validation submitHandleritp., To oczywiście AJAX)

Testowanie jest problemem. W tej chwili próbuję przekazać dane JSON do testu Rack :: Test POST .

Dave Sag
źródło
0

Ja osobiście wolę opcję (3) jako rozwiązanie. Jest używany w prawie wszystkich witrynach, które ma mój były (pracodawca). Oznacza to, że możesz zdobyć programistów, którzy wiedzą wszystko o JavaScript, dziwactwach w przeglądarkach i tym, co nie koduje twojego interfejsu. Muszą tylko wiedzieć „curl xyz, a dostaniesz trochę jsona” i odejdą.

Tymczasem twoi ciężcy back-end faceci mogą kodować dostawców Json. Ci faceci wcale nie muszą myśleć o prezentacji, a zamiast tego martwią się niestabilnymi backendami, limitami czasu, płynną obsługą błędów, pulami połączeń z bazą danych, wątkami i skalowaniem itp.

Opcja 3 zapewnia dobrą, solidną architekturę trójwarstwową. Oznacza to, że rzeczy, które wypluwasz z interfejsu, są przyjazne dla SEO, mogą być przystosowane do pracy ze starymi lub nowymi przeglądarkami (i tymi z wyłączonym JS), i nadal mogą być szablonami po stronie klienta Javascript, jeśli chcesz (więc możesz rób rzeczy takie jak obsługa starych przeglądarek / googlebot za pomocą statycznego HTML, ale wysyłaj dynamiczne wrażenia JS do osób korzystających z najnowszej przeglądarki Chrome lub cokolwiek innego.

We wszystkich przypadkach, w których widziałem opcję 3, była to niestandardowa implementacja niektórych PHP, która nie jest szczególnie przenoszalna między projektami, nie mówiąc już o krainie Open Source. Wydaje mi się, że ostatnio PHP mogło zostać zastąpione Ruby / Rails, ale to samo jest nadal prawdą.

FWIW, $ current_employer mógłby zrobić z Opcją 3 w kilku ważnych miejscach. Szukam dobrego środowiska Ruby, w którym można coś zbudować. Jestem pewien, że mogę skleić wiele klejnotów, ale wolałbym jeden produkt, który zasadniczo zapewnia szablony, „curling”, opcjonalne uwierzytelnianie, opcjonalne rozwiązanie buforowania połączone z memcache / nosql. Nie udało mi się znaleźć niczego spójnego :-(

Ralph Bolton
źródło
0

Budowanie JSON API w Railsach jest pierwszą klasą, klejnot JSONAPI :: Resources wykonuje ciężkie prace w przypadku interfejsu API określonego w http://jsonapi.org .

moduł obsługi pikseli
źródło