wake-up-neo.com

REST JSON API Server und Client trennen?

Ich bin dabei, eine Reihe von Web-Apps von Grund auf neu zu erstellen. (Siehe http://50pop.com/code für eine Übersicht.) Ich möchte, dass auf sie von vielen verschiedenen Clients zugegriffen werden kann: Front-End-Websites, Smartphone-Apps, Back-End-Webservices, usw. Ich möchte also wirklich eine JSON REST API für jede.

Außerdem bevorzuge ich die Arbeit am Back-End. Daher habe ich den Traum, mich nur auf die API zu konzentrieren und jemanden anzuheuern, der die Front-End-Benutzeroberfläche erstellt, sei es eine Website, ein iPhone, Android oder eine andere App.

Bitte helfen Sie mir bei der Entscheidung, wie ich vorgehen soll:

ZUSAMMEN IN Rails

Erstellen Sie eine sehr standardmäßige Rails Web-App. Führen Sie im Controller den Schalter reply_with aus, um entweder JSON oder HTML bereitzustellen. Die JSON-Antwort ist dann meine API.

Pro: Viele Präzedenzfälle. Tolle Standards und viele Beispiele, wie man so vorgeht.

Con: Die API muss nicht unbedingt mit der Webanwendung identisch sein. Gefällt mir nicht, wenn/dann reply_with switch approach. Zwei sehr unterschiedliche Dinge mischen (UI + API).

REST-SERVER + JAVASCRIPT-HEAVY-CLIENT

Erstellen Sie einen JSON-only REST API-Server. Verwenden Sie Backbone oder Ember.js für clientseitiges JavaScript, um direkt auf die API zuzugreifen und Vorlagen im Browser anzuzeigen.

Pro: Ich liebe die Trennung von API und Client. Schlaue Leute sagen, das ist der richtige Weg. In der Theorie großartig. Scheint modern und aufregend.

Con: Nicht viel Präzedenzfall. Nicht viele Beispiele dafür sind gut gelungen. Öffentliche Beispiele (Twitter.com) fühlen sich träge und wenden sich sogar von diesem Ansatz ab.

REST-SERVER + SERVER-SEITIGER HTML-CLIENT

Erstellen Sie einen JSON-only REST API-Server. Erstellen Sie einen einfachen HTML-Website-Client, der auf die REST API zugreift. Weniger clientseitiges JavaScript.

Pro: Ich liebe die Trennung von API und Client. Das Bereitstellen von einfachem HTML5 ist jedoch ziemlich narrensicher und nicht clientintensiv.

Con: Nicht viel Präzedenzfall. Nicht viele Beispiele dafür sind gut gelungen. Frameworks unterstützen dies ebenfalls nicht. Ich bin mir nicht sicher, wie ich es angehen soll.

Besonders auf der Suche nach Ratschlägen aus Erfahrung, nicht nur aus der Theorie.

370
sivers

Bei Boundless haben wir Option 2 vertieft und für Tausende von Studenten eingeführt. Unser Server ist eine JSON REST API (Scala + MongoDB)), und unser gesamter Client-Code wird direkt aus CloudFront bereitgestellt (dh: www.boundless.com ist nur ein Alias ​​für CloudFront).

Vorteile:

  • Innovativ/aufregend
  • Viel fürs Geld: Die API bietet Ihnen die Grundlage für Ihren eigenen Web-Client, mobile Clients, Zugriff von Drittanbietern usw.
  • übermäßig schnelles Laden der Site/Seitenübergänge

Nachteile:

  • Nicht SEO-freundlich/bereit ohne viel mehr Arbeit.
  • Erfordert erstklassige Web-Front-End-Leute, die bereit sind, mit der Realität einer Website-Erfahrung umzugehen, die zu 70% aus Javascript besteht und was das bedeutet.

Ich denke, das ist die Zukunft aller Web-Apps.

Einige Gedanken für die Web-Front-End-Leute (wo all die Neuheit/Herausforderung dieser Architektur gegeben ist):

  • CoffeeScript. Es ist viel einfacher, hochwertigen Code zu erstellen.
  • Rückgrat. Gute Möglichkeit, Ihre Logik und aktive Community zu organisieren.
  • HAMLC. Haml + CoffeeScript Vorlagen => JS.
  • SASS

Wir haben ein Gurtzeug für unsere Front-End-Entwicklung mit dem Namen "Spar" (Single Page App Rocketship) entwickelt, das praktisch die Asset-Pipeline von Rails) ist und auf die Entwicklung von Single-Page-Apps abgestimmt ist Open-Sourcing in den nächsten Wochen auf unserer github Seite, zusammen mit einem Blog-Beitrag, der die Verwendung und die Gesamtarchitektur ausführlicher erklärt.

AKTUALISIEREN:

In Bezug auf die Bedenken der Menschen in Bezug auf Backbone denke ich, dass sie überbewertet sind. Backbone ist weit mehr ein Organisationsprinzip als ein tiefer Rahmen. Die Website von Twitter selbst ist ein riesiges Biest von Javascript, das jeden Eckpfeiler von Millionen von Benutzern und älteren Browsern abdeckt, während Tweets in Echtzeit geladen, Müll gesammelt, viele Multimedia-Inhalte angezeigt werden usw. Von all den 'reinen' Websites, die ich bisher gesehen habe gesehen, Twitter ist die ungerade aus. Es wurden viele beeindruckend komplizierte Apps über JS ausgeliefert, die sich als sehr gut erweisen.

Und Ihre Wahl der Architektur hängt ganz von Ihren Zielen ab. Wenn Sie auf der Suche nach dem schnellsten Weg sind, mehrere Kunden zu unterstützen und Zugang zu guten Front-End-Talenten zu haben, ist die Investition in eine eigenständige API ein guter Weg.

135
Aaron

Sehr gut gefragt. +1. Dies ist für mich mit Sicherheit eine nützliche Referenz für die Zukunft. Auch @Aaron und andere haben der Diskussion einen Mehrwert verliehen. Wie Ruby gilt diese Frage auch für andere Programmierumgebungen.

Ich habe die ersten beiden Optionen verwendet. Erste für zahlreiche Anwendungen und zweite für mein Open Source-Projekt Cowoop

Option 1

Dieser ist ohne Zweifel der beliebteste. Aber ich finde die Implementierung sehr http-ish. Der ursprüngliche Code jeder API befasst sich mit dem Anforderungsobjekt. API-Code ist also mehr als reiner Ruby-/Python-/anderer Sprachcode.

Option 2

Ich habe das immer geliebt.

Diese Option impliziert auch, dass HTML nicht zur Laufzeit auf dem Server generiert wird. Dies ist der Unterschied zwischen Option 2 und Option 3. Sie werden jedoch mithilfe eines Erstellungsskripts als statisches HTML erstellt. Beim Laden auf Client-Seite würde dieser HTML-Code den API-Server als JS-API-Client aufrufen.

  • Die Trennung von Anliegen ist ein großer Vorteil. Und ganz nach Ihren Wünschen (und meinen Wünschen) implementieren Backend-Experten Backend-APIs. Testen Sie sie einfach wie gewöhnlichen Sprachcode, ohne sich Gedanken über Framework-/http-Anforderungscode zu machen.

  • Das ist wirklich nicht so schwierig, wie es auf der Frontend-Seite klingt. API-Aufrufe ausführen und resultierende Daten (meistens JSON) sind für Ihre clientseitige Vorlage oder MVC verfügbar.

  • Weniger serverseitige Verarbeitung. Dies bedeutet, dass Sie sich für Standardhardware/günstigere Server entscheiden können.

  • Einfacheres unabhängiges Testen von Layern und einfacheres Generieren von API-Dokumenten.

Es hat einige Nachteile.

  • Viele Entwickler finden dies überarbeitet und schwer zu verstehen. Daher besteht die Möglichkeit, dass Architektur kritisiert wird.

  • i18n/l10n ist schwer. Da HTML im Wesentlichen statisch generiert wird, benötigt man mehrere Builds pro unterstützter Sprache (was nicht unbedingt eine schlechte Sache ist). Aber auch damit können Sie Eckfälle um l10n/i18n haben und müssen vorsichtig sein.

Option 3

Die Backend-Codierung muss in diesem Fall mit der zweiten Option identisch sein. Die meisten Punkte für Option 2 gelten auch hier.

Webseiten werden mithilfe von serverseitigen Vorlagen zur Laufzeit gerendert. Dies macht i18n/l10n mit etablierteren/akzeptierten Techniken viel einfacher. Möglicherweise ist ein http-Aufruf für einen wesentlichen Kontext, der für das Rendern von Seiten wie Benutzer, Sprache, Währung usw. erforderlich ist, weniger erforderlich. Die serverseitige Verarbeitung wird also durch das Rendern erhöht, möglicherweise jedoch durch weniger http-Aufrufe an den API-Server ausgeglichen.

Da die Seiten nun auf dem Server gerendert werden, ist das Frontend jetzt stärker an die Programmierumgebung gebunden. Bei vielen Anwendungen spielt dies möglicherweise keine Rolle.

Twitter Fall

Soweit ich weiß, wird die erste Seite von Twitter möglicherweise auf dem Server gerendert, für Seitenaktualisierungen stehen jedoch noch einige API-Aufrufe und clientseitige Vorlagen zur Manipulation von DOM zur Verfügung. In diesem Fall müssen Sie also doppelte Vorlagen verwalten, was den Aufwand und die Komplexität erhöht. Anders als bei Twitter kann sich nicht jeder diese Option leisten.

Unser Projekt Stack

Ich benutze zufällig Python. Ich verwende JsonRPC 2.0 anstelle von REST. Ich schlage REST vor, obwohl mir JsonRPC aus verschiedenen Gründen gefällt. Ich benutze unten Bibliotheken. Jemand, der Option 2/3 in Betracht zieht, könnte dies nützlich finden.

  • API Server: Python Ein schnelles Web Micro Framework - Flask
  • Frontend-Server: Nginx
  • Clientseitige MVC: Knockout.js
  • Andere relevante Tools/Bibliotheken:

Mein Fazit und Empfehlung

Option 3 !.

Alles in allem habe ich Option 2 erfolgreich genutzt, mich aber jetzt der Einfachheit halber zu Option 3 hingezogen. Das Generieren statischer HTML-Seiten mit einem Build-Skript und das Bereitstellen dieser Seiten mit einem ultraschnellen Server, der auf das Bereitstellen statischer Seiten spezialisiert ist, ist sehr verlockend (Option 2).

47
Shekhar

Wir haben uns beim Bau von gaug.es für die Nummer 2 entschieden. Ich arbeitete an der API (Ruby, Sinatra usw.) und mein Geschäftspartner, Steve Smith, arbeitete am Front-End (Javascript-Client).

Vorteile:

  1. Bewegen Sie sich schnell parallel. Wenn ich vor Steve arbeiten würde, könnte ich weiterhin APIs für neue Funktionen erstellen. Wenn er vor mir arbeitete, konnte er die API sehr einfach fälschen und die Benutzeroberfläche erstellen.

  2. API kostenlos. Der offene Zugriff auf die Daten in Ihrer App wird schnell zur Standardfunktion. Wenn Sie von Grund auf mit einer API beginnen, erhalten Sie diese kostenlos.

  3. Saubere Trennung. Es ist besser, sich Ihre App als API für Kunden vorzustellen. Sicher, der erste und wichtigste Client kann ein Web-Client sein, aber Sie können damit problemlos andere Clients (iPhone, Android) erstellen.

Nachteile:

  1. Rückwärtskompatibilität. Dies hängt mehr mit einer API zusammen als mit Ihrer direkten Frage, aber sobald Ihre API verfügbar ist, können Sie sie nicht einfach auflösen oder alle Ihre Kunden auflösen. Das bedeutet nicht, dass Sie sich langsamer bewegen müssen, aber es bedeutet, dass Sie häufig zwei Dinge gleichzeitig zum Laufen bringen müssen. Das Hinzufügen zur API oder zu neuen Feldern ist in Ordnung, das Ändern/Entfernen sollte jedoch nicht ohne Versionsverwaltung erfolgen.

Mir fallen gerade keine Nachteile mehr ein.

Fazit: API + JS-Client ist der richtige Weg, wenn Sie eine API veröffentlichen möchten.

P.S. Ich würde auch empfehlen, Ihre API vollständig zu dokumentieren, bevor Sie sie freigeben. Der Prozess der Dokumentation von Gaug.es API hat uns wirklich geholfen, imp

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

28
John Nunemaker

Ich bevorzuge den Weg von # 2 und # 3. Hauptsächlich, weil # 1 die Trennung von Interessen verletzt und alle möglichen Dinge vermischt. Schließlich werden Sie feststellen, dass Sie einen API-Endpunkt benötigen, der über keine passende HTML-Seite/etc verfügt, und Sie werden einen Bach mit vermischten HTML- und JSON-Endpunkten in derselben Codebasis hinlegen. Es verwandelt sich in ein verdammtes Chaos, selbst wenn es MVP ist, müssen Sie es irgendwann neu schreiben, weil es so chaotisch ist, dass es nicht einmal die Rettung wert ist.

Wenn Sie mit # 2 oder # 3 arbeiten, können Sie eine API verwenden, die (größtenteils) unabhängig davon dieselbe Funktion hat. Dies bietet große Flexibilität. Ich bin noch nicht zu 100% auf Backbone/ember/whatever/etc.js verkauft. Ich finde es großartig, aber wie wir bei Twitter sehen, ist dies nicht optimal. ABER ... Twitter ist auch ein riesiges Unternehmenstier und hat Hunderte Millionen Nutzer. Daher kann jede Verbesserung einen enormen Einfluss auf das Endergebnis in verschiedenen Bereichen der verschiedenen Geschäftsbereiche haben. Ich denke, die Entscheidung ist mehr als nur Geschwindigkeit, und sie lässt uns nicht herein. Aber das ist nur meine Meinung. Ich rabattiere jedoch nicht das Backbone und seine Konkurrenten. Diese Apps sind sehr benutzerfreundlich, sehr sauber und reagieren (größtenteils) sehr schnell.

Die dritte Option hat auch eine gewisse Anziehungskraft. Hier würde ich dem Pareto-Prinzip folgen (80/20 Regel) und 20% Ihres Hauptmarkups (oder umgekehrt) auf dem Server rendern und dann den Rest von einem Nice JS-Client (Backbone/etc) ausführen lassen . Möglicherweise kommunizieren Sie nicht zu 100% über den JS-Client mit der REST= api.

Ich denke, dies ist eines dieser "es hängt davon ab" Arten von Problemen und die Antwort ist "es hängt davon ab", was Sie tun, wem Sie dienen und welche Art von Erfahrung Sie möchten, dass sie erhalten. Vorausgesetzt, ich denke, Sie können zwischen 2 oder 3 oder einem Hybrid von ihnen entscheiden.

10
Donn Felker

Ich arbeite derzeit an der Konvertierung eines riesigen CMS von Option 1 zu Option 3, und es läuft gut. Wir haben uns dafür entschieden, das Markup serverseitig zu rendern, da SEO für uns eine große Rolle spielt und wir möchten, dass die Websites auf Mobiltelefonen eine gute Leistung erbringen.

Ich verwende node.js für das Back-End des Clients und eine Handvoll Module, um mir zu helfen. Ich bin noch etwas am Anfang des Prozesses, aber der Grundstein ist gelegt, und es geht darum, die Daten zu überprüfen, um sicherzustellen, dass alles richtig dargestellt wird. Folgendes verwende ich:

  • Express für das Fundament der App.
    (https://github.com/visionmedia/express)
  • Anforderung zum Abrufen der Daten.
    (https://github.com/mikeal/request)
  • Unterstreichen Sie Vorlagen, die serverseitig gerendert werden. Ich verwende diese auf dem Client.
    (https://github.com/documentcloud/underscore)
  • UTML umschließt die Vorlagen des Unterstrichs, damit sie mit Express funktionieren.
    (https://github.com/mikefrey/utml)
  • Upfront sammelt Vorlagen und lässt Sie auswählen, welche an den Client gesendet werden.
    (https://github.com/mrDarcyMurphy/upfront)
  • Express Expose übergibt die abgerufenen Daten, einige Module und Vorlagen an das Front-End.
    (https://github.com/visionmedia/express-expose)
  • Backbone erstellt Modelle und Ansichten auf dem Front-End, nachdem die weitergegebenen Daten verschluckt wurden.
    (https://github.com/documentcloud/backbone)

Das ist der Kern des Stapels. Einige andere Module, die ich hilfreich fand:

  • fleck (https://github.com/trek/fleck)
  • moment (https://github.com/timrwood/moment)
  • stift (https://github.com/LearnBoost/stift)
  • smoosh (https://github.com/fet/smoosh)
    … Obwohl ich mich mit Grunzen befasse (https://github.com/cowboy/grunzen)
  • konsolen-Trace (//github.com/LearnBoost/console-trace).

Nein, ich verwende kein Coffeescript.

Diese Option funktioniert sehr gut für mich. Die Modelle im Back-End sind nicht vorhanden, da die Daten, die wir von der API erhalten, gut strukturiert sind und ich sie wörtlich an das Front-End weitergebe. Die einzige Ausnahme ist unser Layoutmodell, in dem ich ein einzelnes Attribut hinzufüge, das das Rendern intelligenter und leichter macht. Ich habe dafür keine ausgefallene Modellbibliothek verwendet, sondern nur eine Funktion, die das, was ich bei der Initialisierung benötige, hinzufügt und sich selbst zurückgibt.

(Entschuldigung für die seltsamen Links, ich bin zu viel von einem n00b für einen Stapelüberlauf, als dass ich so viele posten könnte.)

7
Darcy Murphy

Wir verwenden die folgende Variante von # 3: Machen Sie einen JSON-only REST API-Server. Machen Sie einen HTML-Website-Server. Der HTML-Webserver ist nicht, wie in Ihrer Variante, ein Client für die = REST API-Server. Stattdessen handelt es sich um Peers. Nicht weit unter der Oberfläche befindet sich eine interne API, die die Funktionalität bietet, die die beiden Server benötigen.

Wir kennen keinen Präzedenzfall, also ist es eine Art Experiment. Bisher (kurz vor der Beta-Version) hat es ziemlich gut geklappt.

7
Thomas Becker

Normalerweise wähle ich die zweite Option und verwende Rails zum Erstellen der API und das Backbone für das JS-Zeug. Mit ActiveAdmin können Sie sogar ein kostenloses Admin-Panel erhalten Ich habe Dutzende von mobilen Apps mit dieser Art von Backend ausgeliefert. Es hängt jedoch stark davon ab, ob Ihre App interaktiv ist oder nicht.

Ich habe am letzten RubyDay.it : http://www.slideshare.net/matteocollina/enter-the-app-era-with-Ruby-on eine Präsentation zu diesem Ansatz gemacht -Rails-Rubyday

Bei der dritten Option möchten Sie möglicherweise pajax probieren, um die Reaktionsfähigkeit der zweiten Option zu erhalten, wie dies Github tut.

7
Matteo Collina

Ich bin ungefähr zwei Monate in einem dreimonatigen Projekt, das den zweiten Ansatz verfolgt, den Sie hier skizziert haben. Wir verwenden eine RESTful API-Serverseite mit backbone.js auf der Vorderseite. Handlebars.js verwaltet die Vorlagen und jQuery verwaltet die AJAX- und DOM-Manipulation. Bei älteren Browsern und Suchmaschinen haben wir uns auf das serverseitige Rendern beschränkt, verwenden jedoch dieselben HTML-Vorlagen wie das Frontend für die Lenker mit Mozilla Rhino.

Wir haben diesen Ansatz aus vielen verschiedenen Gründen gewählt, sind uns jedoch sehr bewusst, dass er ein wenig riskant ist, da er noch nicht in großem Umfang bewiesen wurde. Trotzdem läuft bis jetzt alles reibungslos.

Bisher haben wir nur mit einer API gearbeitet, aber in der nächsten Phase des Projekts werden wir mit einer zweiten API arbeiten. Der erste ist für große Datenmengen gedacht, und der zweite verhält sich eher wie ein CMS über eine API.

Bei der Auswahl dieser Infrastruktur war es von entscheidender Bedeutung, dass diese beiden Teile des Projekts völlig unabhängig voneinander agieren. Wenn Sie nach einer Architektur suchen, mit der Sie verschiedene unabhängige Ressourcen ohne Abhängigkeiten mashupen können, ist dieser Ansatz einen Blick wert.

Ich fürchte, ich bin kein Ruby Mann, daher kann ich die anderen Ansätze nicht kommentieren. Manchmal ist es in Ordnung, ein Risiko einzugehen. In anderen Fällen ist es besser, auf Nummer sicher zu gehen. Sie müssen sich je nach Art des Projekts entscheiden.

Viel Glück bei Ihrer Wahl hier. Ich bin gespannt, was andere mit Ihnen teilen.

6

Ich mag # 3, wenn meine Website keine 100% CRUD-Implementierung meiner Daten sein wird. Welches ist noch zu passieren.

Ich bevorzuge Sinatra und teile die App einfach in ein paar verschiedene Rack-Apps mit unterschiedlichen Zwecken auf. Ich erstelle eine API-spezifische Rack-App, die das abdeckt, was ich für die API benötige. Dann vielleicht eine User-Rack-App, die meine Webseite präsentiert. Manchmal fragt diese Version bei Bedarf die API ab, normalerweise befasst sie sich jedoch nur mit der HTML-Site.

Ich mache mir darüber keine Sorgen und führe nur eine Persistenz-Layer-Abfrage von der Benutzerseite aus, wenn ich sie benötige. Ich mache mir keine allzu großen Sorgen um eine vollständige Trennung, da sie normalerweise unterschiedlichen Zwecken dienen.

Hier ist ein sehr einfaches Beispiel für die Verwendung mehrerer Rack-Apps. Ich habe dort ein Beispiel für eine schnelle Abfrage hinzugefügt, damit Sie sehen können, wie es auf die API-App zutrifft. Sie können sehen, wie einfach es mit sinatra und dem Mounten mehrerer Rack-Apps mit unterschiedlichen Zwecken sein kann.

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

4
Dusty

Ich habe mich für die Architektur von Option 2 für Infiniforms entschieden, da sie eine hervorragende Möglichkeit bietet, die Benutzeroberfläche von der Geschäftslogik zu trennen.

Dies hat den Vorteil, dass die API-Server unabhängig von den Webservern skaliert werden können. Wenn Sie mehrere Clients haben, müssen die Websites nicht im gleichen Maße skaliert werden wie die Webserver, da einige Clients auf Telefonen, Tablets oder Desktops basieren.

Dieser Ansatz bietet Ihnen auch eine gute Basis für das Öffnen Ihrer API für Ihre Benutzer, insbesondere wenn Sie Ihre eigene API verwenden, um alle Funktionen für Ihre Website bereitzustellen.

1
Karl Gjertsen

Eine sehr nette Frage und ich bin überrascht, da ich dachte, dass dies heutzutage eine sehr häufige Aufgabe ist, so dass ich für dieses Problem viele Ressourcen habe, die sich jedoch als nicht wahr herausstellten.

Meine Gedanken sind wie folgt: - Erstellen Sie ein Modul, das die gemeinsame Logik zwischen den API-Controllern und HTML-Controllern aufweist ohne Rückgabe von JSON oder Rendering von HTML, und fügen Sie dieses Modul dann sowohl in den HTML-Controller als auch in den API-Controller ein was auch immer Sie wollen, also zum Beispiel:

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
1
Loai Ghoraba

Für atyourservice.com.cy verwenden wir serverseitig gerenderte Vorlagen für Seiten, um den jeweiligen Teil abzudecken. Und Verwenden der API für Interaktionen nach dem Laden der Seite. Da unser Framework MVC ist, werden alle Controller-Funktionen auf JSON- und HTML-Ausgabe dupliziert. Vorlagen sind sauber und erhalten nur ein Objekt. Dies kann in Sekunden zu js Vorlagen umgewandelt werden. Wir pflegen immer die serverseitigen Templates und konvertieren sie auf Anfrage einfach auf js zurück.

1
xatzistnr

Einige gute Antworten hier bereits - ich würde definitiv # 2 oder # 3 empfehlen - die Trennung ist konzeptionell aber auch in der Praxis gut.

Es kann schwierig sein, Auslastungs- und Datenverkehrsmuster für eine API vorherzusagen, und Kunden, die die API unabhängig voneinander bereitstellen und skalieren, haben es leichter. Wenn Sie dies mit menschlichen Webzugriffsmustern tun müssen, ist es weniger einfach. Außerdem wird Ihre API-Nutzung möglicherweise viel schneller skaliert als Ihr Webclient, und Sie können sehen, wohin Sie Ihre Bemühungen richten müssen.

Zwischen # 2 # 3 hängt es wirklich von Ihren Zielen ab - ich würde zustimmen, dass # 2 wahrscheinlich die Zukunft von Webapps ist - aber vielleicht möchten Sie etwas Unkomplizierteres, wenn dieser Kanal nur einer von vielen sein wird!

1
steve

Isomorphes Rendering und progressive Verbesserung. Welches ist, was ich denke, dass Sie in Option drei geleitet wurden.

isomorphes Rendern bedeutet, dass Sie dieselbe Vorlage verwenden, um Markup-Server-Seite zu generieren, die Sie im clientseitigen Code verwenden. Wählen Sie eine Template-Sprache mit guten Server- und Client-Implementierungen. Erstellen Sie vollständig gebackenes HTML für Ihre Benutzer und senden Sie es über das Kabel. Verwende auch Caching.

progressive Verbesserung bedeutet, dass Sie mit der clientseitigen Ausführung, dem Rendern und dem Abhören von Ereignissen beginnen, sobald Sie alle Ressourcen heruntergeladen haben und die Client-Funktionen bestimmen können. Rückgriff auf funktionsfähige Funktionen ohne Clientskript, wo immer dies möglich ist, um die Zugänglichkeit und Abwärtskompatibilität zu gewährleisten.

Ja, natürlich schreibe eine eigenständige JSON-API für diese App-Funktionalität. Aber gehen Sie nicht so weit, dass Sie eine JSON-API für Dinge schreiben, die als statische HTML-Dokumente gut funktionieren.

1
sirtimbly

REST-Server + JavaScript-lastiger Client war das Prinzip, dem ich in meiner letzten Arbeit gefolgt bin.

Der REST-Server wurde implementiert in node.js + Express + MongoDB (sehr gute Schreibleistung) + Mongoose ODM ( ideal zum Modellieren von Daten, einschließlich Validierungen) + CoffeeScript (Ich würde jetzt stattdessen ES2015 verwenden), was für mich gut funktionierte. Node.js mag im Vergleich zu anderen möglichen serverseitigen Technologien noch relativ jung sein, aber es hat mir ermöglicht, eine solide API mit integrierten Zahlungen zu schreiben.

Ich habe Ember.js als JavaScript-Framework verwendet und der größte Teil der Anwendungslogik wurde im Browser ausgeführt. Ich habe SASS (SCSS-spezifisch) für die CSS-Vorverarbeitung verwendet.

Ember ist ein ausgereiftes Framework, das von einer starken Community unterstützt wird. Es ist ein sehr leistungsfähiges Framework, bei dem in letzter Zeit viel Arbeit auf Leistung ausgerichtet ist, wie brandneue Glimmer-Rendering-Engine (inspiriert von React).

Ember Core Team entwickelt gerade FastBoot , mit dem Sie Ihre JavaScript Ember Logik auf der Serverseite (node.js spezifisch) ausführen und vorgerendert senden können HTML-Code Ihrer Anwendung (der normalerweise im Browser ausgeführt wird) für den Benutzer Es ist ideal für die Suchmaschinenoptimierung und die Benutzerfreundlichkeit, da er nicht so lange auf die Anzeige der Seite wartet.

Ember CLI ist ein großartiges Tool, mit dem Sie Ihren Code organisieren können, und das sich gut mit der wachsenden Codebasis skalieren lässt. Ember hat auch ein eigenes Addon-Ökosystem und Sie können aus einer Vielzahl von Ember Addons auswählen. Sie können leicht Bootstrap (in meinem case) oder Foundation und füge es deiner App hinzu.

Um nicht alles über Express bereitzustellen, habe ich mich für die Verwendung von Nginx für die Bereitstellung von Bildern und JavaScript-lastigen Clients entschieden. Die Verwendung von Nginx Proxy war in meinem Fall hilfreich:

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: Ich liebe die Trennung von API und Client. Schlaue Leute sagen, das ist der richtige Weg. In der Theorie großartig. Scheint modern und aufregend.

Ich kann sagen, dass es auch in der Praxis großartig ist. Ein weiterer Vorteil der Trennung von REST API ist, dass Sie sie später für andere Anwendungen wiederverwenden können. In einer perfekten Welt sollten Sie in der Lage sein, dieselbe REST API zu verwenden Nicht nur für Webseiten, sondern auch für mobile Anwendungen, wenn Sie sich dazu entschließen, eine zu schreiben.

Con: Nicht viel Präzedenzfall. Nicht viele Beispiele dafür sind gut gelungen. Öffentliche Beispiele (Twitter.com) fühlen sich träge und wenden sich sogar von diesem Ansatz ab.

Die Dinge sehen jetzt anders aus. Es gibt viele Beispiele dafür, wie man REST API + viele Clients, die es konsumieren.

1
Daniel Kmak

Ich persönlich bevorzuge Option (3) als Lösung. Es wird an fast allen Standorten eingesetzt, die ein früherer (bekannter) Arbeitgeber von mir hat. Es bedeutet, dass Sie einige Front-End-Entwickler finden können, die alles über Javascript, Browser-Macken und so weiter wissen, um Ihr Front-End zu verschlüsseln. Sie müssen nur "curl xyz and you get some json" kennen und los geht's.

In der Zwischenzeit können Ihre schwergewichtigen Back-End-Leute die Json-Anbieter verschlüsseln. Diese Leute müssen überhaupt nicht über Präsentation nachdenken, sondern müssen sich stattdessen Gedanken über schuppige Backends, Timeouts, angemessene Fehlerbehandlung, Datenbankverbindungspools, Threading und Skalierung usw. machen.

Option 3 bietet Ihnen eine gute, solide dreistufige Architektur. Dies bedeutet, dass die Inhalte, die Sie aus dem Front-End ausspucken, SEO-freundlich sind, mit alten oder neuen Browsern (und jenen mit deaktiviertem JS) verwendet werden können und weiterhin als clientseitiges JavaScript-Templating fungieren können Verwenden Sie zum Beispiel alte Browser/Googlebot mit statischem HTML-Code, und senden Sie JS-basierte dynamische Erlebnisse mit dem neuesten Chrome Browser oder was auch immer) an Benutzer.

In allen Fällen, in denen ich Option 3 gesehen habe, handelt es sich um eine benutzerdefinierte Implementierung von einigen PHP), die nicht speziell zwischen Projekten übertragbar ist, geschweige denn in Open Source-Land. Vermutlich in jüngerer Zeit PHP wurde möglicherweise durch Ruby/Rails ersetzt, aber das Gleiche gilt immer noch.

FWIW, $ current_employer könnte an einigen wichtigen Stellen mit Option 3 zurechtkommen. Ich bin auf der Suche nach einem guten Ruby Framework, in dem ich etwas bauen kann. Ich bin sicher, dass ich eine Menge Edelsteine ​​zusammenkleben kann, aber ich würde ein einzelnes Produkt bevorzugen, das im Großen und Ganzen eine Vorlage bietet , "Eisstockschießen", optionale Authentifizierung, optionale Caching-Lösung mit Memcache-/NOSQL-Anbindung. Da finde ich nichts Kohärentes :-(

0
Ralph Bolton

Ich habe mich für einen hybriden Ansatz entschieden, bei dem wir Sinatra als Basis, ActiveRecord/Postgress usw. verwenden, um Seitenrouten (schlanke Vorlagen) bereitzustellen und eine REST API, die die Web-App verwenden kann Frühe Entwicklungsaufgaben wie das Auffüllen ausgewählter Optionen erfolgen über das Rendern von Hilfsprogrammen in die schlanke Vorlage. Wenn wir uns der Produktion nähern, wird dies jedoch durch einen AJAX) - Aufruf an ein REST) ersetzt = API, während wir uns mehr um die Seitenladegeschwindigkeit und so weiter kümmern.

Dinge, die in Slim einfach zu rendern sind, werden auf diese Weise behandelt, und solche Dinge (Formulare ausfüllen, Formulare empfangen POST Daten aus jQuery.Validations submitHandler usw.) sind offensichtlich AJAX)

Testen ist ein Problem. Im Moment bin ich ratlos versucht, JSON-Daten an ein Rack zu übergeben :: Test POST test .

0
Dave Sag

Das Erstellen einer JSON-API in Rails ist erstklassig. Der JSONAPI :: Resources-Edelstein erledigt das Heben für eine http://jsonapi.org spezifizierte API.

0
pixelhandler