Separare server e client API JSON REST? [chiuso]


371

Sto per creare un sacco di app Web da zero. (Vedi http://50pop.com/code per una panoramica.) Vorrei che potessero avere accesso a molti client diversi: siti Web front-end, app per smartphone, servizi web back-end, ecc. Quindi voglio davvero un API REST JSON per ognuno.

Inoltre, preferisco lavorare sul back-end, quindi sogno ad occhi aperti di concentrarmi esclusivamente sull'API e assumere qualcun altro per creare l'interfaccia utente front-end, che sia un sito Web, un iPhone, un dispositivo Android o un'altra app.

Aiutatemi a decidere quale approccio dovrei adottare:

INSIEME NELLE RAIL

Crea un'app Web Rails molto standard. Nel controller, esegui l'opzione respond_with per servire JSON o HTML. La risposta JSON è quindi la mia API.

Pro: un sacco di precedenti. Grandi standard e molti esempi di fare le cose in questo modo.

Contro: Non necessariamente l'API deve essere uguale all'app Web. Non mi piace se / then reply_with switch approccio. Mescolando due cose molto diverse (UI + API).

REST SERVER + CLIENTE PESANTE JAVASCRIPT

Creare un server API REST solo JSON. Utilizzare Backbone o Ember.js per JavaScript lato client per accedere direttamente all'API, visualizzando i modelli nel browser.

Pro: Adoro la separazione di API e client. Le persone intelligenti dicono che questa è la strada da percorrere. Ottimo in teoria. Sembra all'avanguardia ed eccitante.

Contro: non molto precedente. Non molti esempi di questo fatto bene. Gli esempi pubblici (twitter.com) sembrano lenti e stanno addirittura abbandonando questo approccio.

REST SERVER + CLIENT HTML LATO SERVER

Creare un server API REST solo JSON. Crea un client per siti Web HTML di base, che accede solo all'API REST. Meno JavaScript sul lato client.

Pro: Adoro la separazione di API e client. Ma servire il semplice HTML5 è abbastanza infallibile e non intensivo per il cliente.

Contro: non molto precedente. Non molti esempi di questo fatto bene. Anche i frame non supportano questo. Non sono sicuro di come affrontarlo.

Soprattutto in cerca di consigli dall'esperienza, non solo in teoria.


50
preferiamo generalmente che le domande speculative e concettuali sulla lavagna vengano inviate a programmers.stackexchange.com mentre le domande qui su Stack Overflow dovrebbero contenere il codice sorgente effettivo il 99% delle volte. Ma è una domanda ben fatta e adoro il tuo lavoro, quindi per ora può cadere nell'area grigia.
Jeff Atwood,

2
Qualcuno ha alcuni esempi / fonti (per capire le loro ragioni) per coloro che si stanno allontanando dall'opzione 2?
Víctor López García,

12
@frntk Il motivo originale per cui molte aziende (come Twitter) stavano facendo client Javascript era perché pensavano che sarebbe stato più veloce. Ora si stanno rendendo conto che in realtà è più lento. Vedi engineering.twitter.com/2012/05/… e openmymind.net/2012/5/30/Client-Side-vs-Server-Side-Rendering
Moshe Katz

1
Leggi i commenti nei link sopra. Molte delle ipotesi dell'articolo sono confutate con logica ed esperienza.
Ricalsin,

1
In questi giorni vorresti creare un backend dell'API JSON seguendo le specifiche jsonapi.org ... :)
Askar,

Risposte:


136

A Boundless , abbiamo approfondito l'opzione 2 e l'abbiamo distribuito a migliaia di studenti. Il nostro server è un'API REST JSON (Scala + MongoDB) e tutto il nostro codice client viene fornito direttamente da CloudFront (ovvero: www.boundless.com è solo un alias per CloudFront).

Professionisti:

  • Avanguardia / entusiasmante
  • Un sacco di soldi per il tuo dollaro: l'API ti fornisce la base per il tuo client Web, client mobili, accesso di terze parti, ecc.
  • transizioni di caricamento / pagina del sito estremamente veloci

Contro:

  • SEO friendly / pronto senza molto più lavoro.
  • Richiede gente di front-end Web di prim'ordine che è pronta a far fronte alla realtà di un'esperienza del sito che è javascript al 70% e che cosa significa.

Penso che questo sia il futuro di tutte le app web.

Alcuni pensieri per la gente del front-end web (che è dove tutta la novità / sfida è data questa architettura):

  • CoffeeScript. Molto più facile da produrre codice di alta qualità.
  • Spina dorsale. Ottimo modo per organizzare la tua logica e la community attiva.
  • HAMLC. Modelli Haml + CoffeeScript => JS.
  • SASS

Abbiamo creato un cablaggio per il nostro sviluppo front-end chiamato "Spar" (Single Page App Rocketship) che è effettivamente la pipeline di asset di Rails ottimizzata per lo sviluppo di app a pagina singola. Nelle prossime settimane ci occuperemo di open-source sulla nostra pagina github , insieme a un post sul blog che spiegherà come utilizzarlo e l'architettura generale in modo più dettagliato.

AGGIORNARE:

Per quanto riguarda le preoccupazioni delle persone con Backbone, penso che siano sopravvalutate. La spina dorsale è molto più un principio organizzativo che un quadro profondo. Il sito stesso di Twitter è una gigantesca bestia di Javascript che copre ogni caso angolare tra milioni di utenti e browser legacy, mentre carica tweet in tempo reale, raccolta dei rifiuti, mostra molti contenuti multimediali, ecc. Di tutti i siti j "puri" che ho visto, Twitter è quello strano fuori. Ci sono state molte app incredibilmente complicate fornite tramite JS che funzionano molto bene.

E la tua scelta di architettura dipende interamente dai tuoi obiettivi. Se stai cercando il modo più veloce per supportare più clienti e avere accesso a buoni talenti front-end, investire in un'API autonoma è un ottimo modo per andare.


1
Un piccolo punto da aggiungere: anche se ho sviluppato solo l'opzione n. 1, conosco più sviluppatori di app mobili che stanno iniziando a utilizzare parse.com come backend per consentire un percorso rapido verso il n. 2.
Rhb123,

Cose come Parse e Kinvey sono molto interessanti, non posso dire di aver avuto ancora la possibilità di giocare con loro. Dipende se il tuo valore è nella parte anteriore o posteriore della pila, suppongo
Aaron,

Uso lo stesso approccio con spinejs per il frontend.
Nicolas Goy,

Come gestite un singolo dominio con due applicazioni separate? Per esempio. Ho www.mysite.com e voglio esporre un'API pubblica e pubblicare un front-end su quell'URL. Fedele ai principi REST, mysite.com/product/24 a cui si accede da un browser Web dovrebbe restituire una pagina HTML guardando l'intestazione HTTP Accept e un GET con JSON nell'intestazione Accept su mysite.com/product/24 dovrebbe restituire JSON .
Erich,

Come farebbe AngularJS a fare questo?
Ankan-Zerob,

48

Molto ben chiesto +1. Di sicuro, questo è un utile riferimento futuro per me. Anche @Aaron e altri hanno aggiunto valore alla discussione. Come Ruby, questa domanda è ugualmente applicabile ad altri ambienti di programmazione.

Ho usato le prime due opzioni. Il primo per numerose applicazioni e il secondo per il mio progetto open source Cowoop

opzione 1

Questo è senza dubbio il più popolare. Ma trovo che l'implementazione sia molto http-ish. Il codice iniziale di ogni API riguarda la gestione dell'oggetto richiesta. Quindi il codice API è più di un codice ruby ​​/ python / altro linguaggio puro.

opzione 2

L'ho sempre amato.

Questa opzione implica anche che HTML non è generato in fase di esecuzione sul server. Ecco come l'opzione 2 è diversa dall'opzione 3. Ma sono compilati come HTML statico usando uno script di compilazione. Se caricati sul lato client, questi HTML chiamerebbero il server API come client API JS.

  • La separazione delle preoccupazioni è un grande vantaggio. E molto a tuo piacimento (e mio) gli esperti di back-end implementano API di back-end, testandoli facilmente come al solito codice di lingua senza preoccuparsi del codice di richiesta framework / http.

  • Questo in realtà non è così difficile come sembra dal lato frontend. Effettua chiamate API e i dati risultanti (principalmente json) sono disponibili per il modello lato client o MVC.

  • Meno elaborazione lato server. Significa che potresti optare per hardware di merce / server meno costoso.

  • Più facile testare i livelli in modo indipendente, più facile generare documenti API.

Ha alcuni aspetti negativi.

  • Molti sviluppatori lo trovano troppo ingegnerizzato e difficile da capire. Quindi è probabile che l'architettura possa essere criticata.

  • i18n / l10n è difficile. Dato che l'HTML viene essenzialmente generato, i tempi di compilazione sono statici, sono necessarie più build per ogni lingua supportata (che non è necessariamente una cosa negativa). Ma anche con quello potresti avere casi angolari intorno a l10n / i18n e devi stare attento.

Opzione 3

La codifica back-end in questo caso deve essere uguale alla seconda opzione. La maggior parte dei punti per l'opzione 2 sono applicabili anche qui.

Le pagine Web vengono visualizzate in fase di esecuzione utilizzando modelli lato server. Ciò rende i18n / l10n molto più semplice con tecniche più consolidate / accettate. Potrebbe essere una chiamata HTTP in meno per alcuni contesti essenziali necessari per il rendering della pagina come utente, lingua, valuta, ecc. Quindi l'elaborazione lato server è aumentata con il rendering ma probabilmente compensata da meno chiamate http al server API.

Ora che le pagine sono rese server su server, frontend è ora più legato all'ambiente di programmazione. Questo potrebbe non essere nemmeno una considerazione per molte applicazioni.

Caso Twitter

A quanto ho capito, Twitter potrebbe eseguire il rendering della pagina iniziale sul server ma per gli aggiornamenti di pagina ha ancora alcune chiamate API e modelli lato client per manipolare DOM. Quindi, in tal caso, hai dei modelli doppi da mantenere che aggiungono un certo sovraccarico e complessità. Non tutti possono permettersi questa opzione, a differenza di Twitter.

Il nostro progetto Stack

Mi capita di usare Python. Uso JsonRPC 2.0 invece di REST. Suggerisco REST, anche se mi piace l'idea di JsonRPC per vari motivi. Uso le librerie di seguito. Qualcuno che considera l'opzione 2/3 potrebbe trovarlo utile.

  • Server API: Python Un micro framework Web veloce: Flask
  • Server frontend: Nginx
  • MVC lato client: Knockout.js
  • Altri strumenti / librerie rilevanti:

La mia conclusione e raccomandazione

Opzione 3 !.

Detto questo, ho usato con successo l'opzione 2, ma ora mi applico all'opzione 3 per semplicità. Generare pagine HTML statiche con script di compilazione e servirle con uno dei server ultra veloci specializzati nel servire pagine statiche è molto allettante (Opzione 2).


Mi piace anche l'opzione 2, ma l'opzione 3 ha molti vantaggi da cui non possiamo liberarci. Sto cercando di trovare una soluzione idratica che combini sia opt2 + opt3, ma porterà a mal di testa come Twitter.
Blue Smith,

Adoro l'opzione 3 e intendo utilizzarla per un progetto attuale. Qualche esempio o git repo a cui puoi chiedere aiuto?
AmaChefe,

@AmaChefe I wish. Per il progetto attuale in cui la SEO è cruciale, utilizziamo l'opzione 3. Ma il codice non è open source. Usiamo flask + jinja2 e knockout / reaction.js.
Shekhar,

28

Abbiamo optato per il n. 2 quando abbiamo creato gaug.es. Ho lavorato sull'API (ruby, sinatra, ecc.) E il mio socio in affari, Steve Smith, ha lavorato sul front-end (client javascript).

Professionisti:

  1. Muoviti rapidamente in parallelo. Se avessi lavorato davanti a Steve, avrei potuto continuare a creare API per nuove funzionalità. Se avesse lavorato davanti a me, avrebbe potuto falsificare l'API molto facilmente e creare l'interfaccia utente.

  2. API gratuitamente. Avere accesso aperto ai dati nella tua app sta rapidamente diventando una funzionalità standard. Se inizi con un'API da zero, ottieni questo gratuitamente.

  3. Separazione pulita. È meglio pensare alla tua app come a un'API con i client. Certo, il primo e più importante client potrebbe essere un Web, ma ti consente di creare facilmente altri client (iPhone, Android).

Contro:

  1. Compatibilità con le versioni precedenti. Questo è più correlato a un'API che alla tua domanda diretta, ma una volta che l'API è disponibile, non puoi semplicemente romperla o rompi tutti e due i tuoi clienti. Questo non significa che devi muoverti più lentamente, ma significa che devi spesso far funzionare due cose contemporaneamente. L'aggiunta all'API o ai nuovi campi va bene, ma la modifica / rimozione non dovrebbe essere eseguita senza il controllo delle versioni.

Non riesco a pensare a più svantaggi in questo momento.

Conclusione: il client API + JS è la strada da percorrere se si prevede di rilasciare un'API.

PS Vorrei anche raccomandare di documentare completamente la tua API prima di rilasciarla. Il processo di documentazione dell'API Gaug.es ci ha davvero aiutato a imp

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


13
Posso chiederti come autenticare il frontend Web con l'API REST? Ho visto che hai bisogno di una chiave API per comunicare con l'API che si ottiene accedendo al tuo profilo utente. Ma come fa il client Web a ottenere la sua chiave API, se sai cosa intendo?
Sebastian Wramba,

@SebastianWramba Questo è in ritardo, ma dal momento che il tuo commento ha ottenuto 12 voti ... Guarderei qualcosa come l'autorizzazione della password di OAuth2 . Se sei il creatore dell'app che chiama l'API, questo è l'approccio che probabilmente desideri, poiché non utilizza direttamente la chiave API. Se si tratta di un'app di terze parti, l'utente ha effettuato l'accesso al proprio sito Web per ottenere la propria chiave API, quindi l'utente utilizza quella chiave (e tutte le altre credenziali necessarie) per accedere all'API tramite la propria app, sito Web, ecc.
GreeKatrina

10

Preferisco seguire il percorso n. 2 e n. 3. Principalmente perché il n. 1 viola la separazione delle preoccupazioni e mescola tutti i tipi di cose. Alla fine scoprirai la necessità di avere un endpoint API che non abbia una pagina HTML / etc corrispondente e ti troverai in un torrente con endpoint HTML e JSON mescolati nella stessa base di codice. Si trasforma in un disastro eccentrico, anche se il suo MVP, alla fine dovrai riscriverlo perché è così disordinato che non vale nemmeno la pena recuperarlo.

Andare con # 2 o # 3 ti consente di avere completamente un'API che agisce allo stesso modo (per la maggior parte) a prescindere. Questo offre una grande flessibilità. Non sono ancora venduto al 100% su Backbone / ember / qualunque / etc.js. Penso che sia grandioso, ma come stiamo vedendo con Twitter questo non è ottimale. MA ... Twitter è anche una grande bestia di un'azienda e ha centinaia di milioni di utenti. Pertanto, qualsiasi miglioramento può avere un impatto enorme sui profitti in varie aree di varie unità aziendali. Penso che ci sia molto di più nella decisione oltre alla sola velocità e non ci stanno lasciando entrare. Ma questa è solo la mia opinione. Tuttavia, non sconto la spina dorsale e i suoi concorrenti. Queste app sono fantastiche da usare, molto pulite e reattive (per la maggior parte).

La terza opzione ha anche un certo fascino valido. È qui che seguirò il principio di Pareto (regola 80/20) e fare in modo che il 20% del markup principale (o viceversa) venga visualizzato sul server e quindi un buon client JS (backbone / etc) esegua il resto . È possibile che non si stia comunicando al 100% con l'API REST tramite il client JS, ma se necessario si farà un po 'di lavoro per migliorare l'esperienza del suer.

Penso che questo sia uno di quei "dipende" tipi di problemi e la risposta è "dipende" da ciò che stai facendo, da chi stai servendo e dal tipo di esperienza che vuoi che ricevano. Dato che penso che tu possa decidere tra 2 o 3 o un ibrido.


+1 all'ibrido di 2 e 3
Ujjwal Ojha

7

Attualmente sto lavorando per convertire un enorme CMS dall'opzione 1 all'opzione 3, e sta andando bene. Abbiamo scelto di eseguire il rendering del markup sul lato server perché la SEO è un grosso problema per noi e vogliamo che i siti funzionino bene sui telefoni cellulari.

Sto usando node.js per il back-end del client e una manciata di moduli per aiutarmi. Sono un po 'all'inizio del processo, ma le basi sono stabilite ed è una questione di andare oltre i dati assicurandomi che tutto renda giusto. Ecco cosa sto usando:

  • Esprimere per la fondazione dell'app.
    (https://github.com/visionmedia/express)
  • Richiesta di recuperare i dati.
    (https://github.com/mikeal/request)
  • Sottolineatura dei modelli che vengono visualizzati sul lato server. Li riutilizzo sul client.
    (https://github.com/documentcloud/underscore)
  • UTML avvolge i modelli di sottolineatura per farli funzionare con Express.
    (https://github.com/mikefrey/utml)
  • Upfront raccoglie i modelli e ti consente di scegliere quali vengono inviati al client.
    (https://github.com/mrDarcyMurphy/upfront)
  • Express Expose passa i dati recuperati, alcuni moduli e modelli al front-end.
    (https://github.com/visionmedia/express-expose)
  • Backbone crea modelli e viste sul front-end dopo aver ingoiato i dati passati.
    (https://github.com/documentcloud/backbone)

Questo è il nocciolo dello stack. Alcuni altri moduli che ho trovato utili:

  • fleck (https // github.com / trek / fleck)
  • moment (https // github.com / timrwood / moment)
  • stilo (https // github.com / LearnBoost / stilo)
  • smoosh (https // github.com / fat / smoosh)
    ... anche se sto guardando nel grugnito (https // github.com / cowboy / grunt)
  • console trace (//github.com/LearnBoost/console-trace).

No, non sto usando coffeescript.

Questa opzione funziona davvero bene per me. I modelli sul back-end sono inesistenti perché i dati che otteniamo dall'API sono ben strutturati e li sto passando testualmente al front-end. L'unica eccezione è il nostro modello di layout in cui aggiungo un singolo attributo che rende il rendering più intelligente e leggero. Non ho usato nessuna libreria di modelli fantasiosi per questo, solo una funzione che aggiunge ciò di cui ho bisogno durante l'inizializzazione e restituisce se stessa.

(scusate per i collegamenti strani, sono troppo un n00b per overflow dello stack per farmi pubblicare così tanti)


1
Quindi stai eseguendo il rendering del markup sul lato server ma stai ancora dando modelli al client e stai usando Backbone?
Shannon,

7

Usiamo la seguente variante di # 3: creare un server API REST solo JSON. Crea un server Web HTML. Il web server HTML non è, come nella tua variante, un client per il server API REST. Invece, i due sono pari. Non lontano dalla superficie, c'è un'API interna che fornisce le funzionalità di cui i due server hanno bisogno.

Non siamo a conoscenza di alcun precedente, quindi è un po 'sperimentale. Finora (sta per entrare in beta), ha funzionato abbastanza bene.


Sto pensando a questa opzione per evitare alcuni problemi legati all'essere un client API adeguato, come l'autenticazione. Mi piacerebbe sapere di più su come hai strutturato il tutto e su come gestisci la separazione e la comunicazione tra le tre diverse parti. C'è qualcosa che potrei leggere? Grazie!
MartinodF,

2
@MartinodF Ospitiamo su Google App Engine, che si limita a Java o Python. Volevo usare Python, ma sono stato forzato in Java perché sgranocchiamo i numeri (non possiamo estendere Py con C / C ++ su GAE). Abbiamo scelto Stripes (Stripes, non Struts, non Spring) per il framework di presentazione. Molto contento di quello. L'intera cosa è un'app Java su GAE. La funzionalità principale è implementata in un gruppo di pacchetti Java ed esposta in un'API interna. Esiste un servlet che fornisce il servizio REST JSON e un altro configurato come app Web Stripes. Dal momento che è tutta un'app Java GAE, la comunicazione è banale.
Thomas Becker,

Grazie per la comprensione, è molto utile!
MartinodF,

7

Di solito vado per la seconda opzione, usando Rails per costruire l'API e backbone per le cose JS. Puoi anche ottenere un pannello di amministrazione gratuitamente usando ActiveAdmin . Ho spedito decine di app mobili con questo tipo di backend. Tuttavia, dipende fortemente se l'app è interattiva o meno.

Ho fatto una presentazione su questo approccio nell'ultimo RubyDay.it : http://www.slideshare.net/matteocollina/enter-the-app-era-with-ruby-on-rails-rubyday

Per la terza opzione, al fine di ottenere la reattività della seconda, potresti provare pajax come fa Github.


6

Sono circa 2 mesi in un progetto di 3 mesi che adotta il secondo approccio che hai delineato qui. Usiamo un lato server API RESTful con backbone.js sul davanti. Handlebars.js gestisce i modelli e jQuery gestisce la manipolazione AJAX e DOM. Per i browser più vecchi e gli spider di ricerca siamo tornati al rendering lato server, ma stiamo usando gli stessi modelli HTML del frontend del manubrio usando Mozilla Rhino.

Abbiamo scelto questo approccio per molte ragioni diverse, ma siamo consapevoli che è un po 'rischioso dato che non è stato ancora dimostrato su larga scala. Tutti uguali, tutto sta andando abbastanza liscio finora.

Finora abbiamo appena lavorato con un'API, ma nella prossima fase del progetto lavoreremo con una seconda API. Il primo è per grandi quantità di dati e il secondo agisce più come un CMS tramite un'API.

Avere questi due elementi del progetto completamente indipendenti l'uno dall'altro è stata una considerazione chiave nella scelta di questa infrastruttura. Se stai cercando un'architettura per combinare diverse risorse indipendenti senza dipendenze, questo approccio vale la pena dare un'occhiata.

Temo di non essere un tipo rubino, quindi non posso commentare gli altri approcci. A volte va bene rischiare. Altre volte è meglio giocarlo in sicurezza. Ti devi conoscere a seconda del tipo di progetto.

Buona fortuna con la tua scelta qui. Mi piacerebbe vedere cosa condividono anche gli altri.


1
Quindi rilevi se la richiesta proviene da un bot di ricerca e offri HTML pre-renderizzato se lo è e modelli JS + se non lo sono?
Shannon,

4

Mi piace # 3 quando il mio sito Web non sarà un'implementazione CRUD al 100% dei miei dati. Che deve ancora accadere.

Preferisco Sinatra e suddividerò l'app in diverse app per rack con scopi diversi. Creerò un'app per rack specifica per l'API che coprirà ciò di cui ho bisogno per l'API. Quindi forse un'app per rack utente che presenterà la mia pagina web. A volte quella versione interrogherà l'API se necessario, ma di solito si occupa solo del sito html.

Non mi preoccupo e faccio una query sul livello di persistenza dal lato utente se ne ho bisogno. Non mi preoccupo eccessivamente di creare una separazione completa poiché di solito finiscono per servire a scopi diversi.

Ecco un esempio molto semplice di utilizzo di più app per rack. Ho aggiunto un rapido esempio jquery lì per farti vedere colpire l'app API. Puoi vedere quanto può essere semplice con Sinatra e montare più app per rack con scopi diversi.

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


1

Alcune ottime risposte qui già - consiglio vivamente n. 2 o n. 3 - la separazione è buona concettualmente ma anche nella pratica.

Può essere difficile prevedere cose come i modelli di carico e di traffico su un'API e i clienti che vedono servire l'API in modo indipendente hanno un tempo più facile di provisioning e ridimensionamento. Se devi farlo in armonia con i modelli di accesso al web umano è meno facile. Inoltre, l'utilizzo dell'API potrebbe aumentare di molto più rapidamente del tuo client Web e quindi puoi vedere dove indirizzare i tuoi sforzi.

Tra # 2 # 3 dipende davvero dai tuoi obiettivi - concordo sul fatto che # 2 è probabilmente il futuro delle webapp - ma forse vuoi qualcosa di più semplice se quel canale sarà solo uno dei tanti!


1

Per atyourservice.com.cy stiamo usando modelli di rendering lato server per pagine, in particolare per coprire la parte se. E utilizzo dell'API per le interazioni dopo il caricamento della pagina. Poiché il nostro framework è MVC, tutte le funzioni del controller sono duplicate in output json e output html. I modelli sono puliti e ricevono solo un oggetto. Questo può essere trasformato in template js in pochi secondi. Manteniamo sempre i modelli sul lato server e riconvertiamo semplicemente js su richiesta.


1

Rendering isomorfo e miglioramento progressivo. Questo è quello che penso tu fossi diretto nell'opzione tre.

rendering isomorfo significa utilizzare lo stesso modello per generare markup lato server come si usa nel codice lato client. Scegli un linguaggio di template con buone implementazioni lato server e lato client. Crea HTML completamente cotto per i tuoi utenti e invialo via cavo. Usa anche la cache.

il miglioramento progressivo significa iniziare a eseguire l'esecuzione e il rendering lato client e l'ascolto di eventi una volta che hai scaricato tutte le risorse e puoi determinare le capacità di un client. Tornando alla funzionalità funzionale senza client script ove possibile per accessibilità e retrocompatibilità.

Sì, ovviamente scrivi un'API json indipendente per questa funzionalità dell'app. Ma non andare così lontano che scrivi api json per cose che funzionano bene come documenti HTML statici.


1

Server REST + client JavaScript pesante era il principio che ho seguito nel mio recente lavoro.

Il server REST è stato implementato in node.js + Express + MongoDB (ottime prestazioni di scrittura) + Mongoose ODM (ottimo per i dati di modellazione, convalide incluse) + CoffeeScript (ora andrei ES2015) che ha funzionato bene per me. Node.js potrebbe essere relativamente giovane rispetto ad altre possibili tecnologie lato server, ma mi ha permesso di scrivere API solide con pagamenti integrati.

Ho usato Ember.js come framework JavaScript e la maggior parte della logica dell'applicazione è stata eseguita nel browser. Ho usato SASS (in particolare SCSS) per la pre-elaborazione CSS.

Ember è un framework maturo supportato da una forte community. È un framework molto potente con un sacco di lavoro recentemente focalizzato sulle prestazioni, come il nuovissimo motore di rendering Glimmer (ispirato a React).

Ember Core Team sta sviluppando FastBoot , che consente di eseguire la logica Ember JavaScript sul lato server (in particolare node.js) e di inviare all'utente HTML pre-renderizzato (che normalmente verrebbe eseguito nel browser). È ottimo per la SEO e l'esperienza utente in quanto non aspetta così tanto che venga visualizzata la pagina.

Ember CLI è un ottimo strumento che ti aiuta a organizzare il tuo codice e ha fatto bene a ridimensionarsi con una base di codice in crescita. Ember ha anche il proprio ecosistema di addon e puoi scegliere tra una varietà di addon Ember . Puoi facilmente prendere Bootstrap (nel mio caso) o Foundation e aggiungerlo alla tua app.

Per non servire tutto tramite Express, ho scelto di utilizzare nginx per servire immagini e client con JavaScript elevato. L'uso del proxy nginx è stato utile nel mio caso:

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: Adoro la separazione di API e client. Le persone intelligenti dicono che questa è la strada da percorrere. Ottimo in teoria. Sembra all'avanguardia ed eccitante.

Posso dire che è anche ottimo in pratica. Un altro vantaggio della separazione dell'API REST è che puoi riutilizzarlo in seguito per altre applicazioni. Nel mondo perfetto dovresti essere in grado di utilizzare la stessa API REST non solo per la pagina Web, ma anche per le applicazioni mobili se decidi di scriverne una.

Contro: non molto precedente. Non molti esempi di questo fatto bene. Gli esempi pubblici (twitter.com) sembrano lenti e stanno addirittura abbandonando questo approccio.

Le cose sembrano diverse ora. Esistono molti esempi di utilizzo dell'API REST + molti client che la consumano.


1

Ho deciso di optare per l'architettura dell'opzione n. 2 per Infiniforms , in quanto ha fornito un ottimo modo per separare l'interfaccia utente dalla logica aziendale.

Un vantaggio è che i server API possono scalare indipendentemente dai server Web. Se si dispone di più client, i siti Web non dovranno ridimensionarsi nella stessa misura dei server Web, poiché alcuni client saranno basati su telefono / tablet o desktop.

Questo approccio offre anche una buona base per l'apertura dell'API ai tuoi utenti, soprattutto se usi la tua API per fornire tutte le funzionalità del tuo sito web.


1

Una domanda molto bella e sono sorpreso mentre pensavo che questo sia un compito molto comune al giorno d'oggi tale che avrò molte risorse per questo problema, tuttavia si è rivelato non essere vero.

I miei pensieri sono i seguenti: - Creare un modulo che abbia la logica comune tra i controller API e i controller HTML senza restituire json o rendering HTML, e includere questo modulo sia nel controller HTML che nel controller API, quindi fare tutto ciò che si desidera, quindi ad esempio :

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

0

Ho optato per un approccio ibrido in cui utilizziamo Sinatra come base, ActiveRecord / Postgress ecc. Per offrire percorsi di pagina (modelli sottili) per esporre un'API REST che l'app Web può utilizzare. Nei primi sviluppi cose come il popolamento di opzioni selezionate vengono eseguite tramite il rendering degli helper nel modello slim, ma quando ci avviciniamo alla produzione questo viene scambiato per una chiamata AJAX a un'API REST mentre iniziamo a preoccuparci di più sulle velocità di caricamento della pagina e così via.

Le cose facili da estrarre in Slim vengono gestite in questo modo e le cose (compilare moduli, ricevere dati POST da jQuery.Validation submitHandlerecc., È tutto a malincuore AJAX)

Il test è un problema. In questo momento sono sconcertato nel tentativo di passare i dati JSON a un test POST Rack :: Test .


0

Personalmente preferisco l'opzione (3) come soluzione. È utilizzato in quasi tutti i siti di un mio ex datore di lavoro (nome familiare). Significa che puoi ottenere alcuni sviluppatori front-end che sanno tutto di Javascript, stranezze del browser e quant'altro per codificare il tuo front-end. Devono solo sapere "arricciare xyz e otterrai un po 'di json" e se ne vanno.

Nel frattempo, i tuoi ragazzi di back-end pesanti possono codificare i provider Json. Questi ragazzi non hanno bisogno di pensare alla presentazione e si preoccupano invece di backend instabili, timeout, gestione degli errori, pool di connessioni al database, threading e ridimensionamento ecc.

L'opzione 3 offre un'architettura a tre livelli valida e solida. Significa che le cose che sputi dal front-end sono SEO friendly, possono essere fatte funzionare con browser vecchi o nuovi (e quelli con JS disattivati), e potresti comunque essere un modello JavaScript sul lato client se vuoi (così puoi fare cose come gestire vecchi browser / googlebot con HTML statico, ma inviare esperienze dinamiche costruite da JS alle persone che utilizzano l'ultimo browser Chrome o altro).

In tutti i casi in cui ho visto l'opzione 3, è stata un'implementazione personalizzata di alcuni PHP che non è particolarmente trasferibile tra progetti, per non parlare della terra Open Source. Suppongo che più recentemente PHP potrebbe essere stato sostituito con Ruby / Rails, ma lo stesso tipo di cose è ancora vero.

FWIW, $ current_employer potrebbe fare con l'opzione 3 in un paio di posti importanti. Sto cercando un buon framework Ruby in cui costruire qualcosa. Sono sicuro di poter incollare insieme un sacco di gemme, ma preferirei un singolo prodotto che fornisce in generale una soluzione di memorizzazione nella cache basata su memcache / nosql basata su modelli, curling, autenticazione opzionale. Lì non riesco a trovare qualcosa di coerente :-(


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.