4 min read

Webapp MVC client e server con Rails 3.1 - Tecnologie, vantaggi e rischi

Le applicazioni/siti web si stanno muovendo con forza verso nuovi pattern web. Se una volta avere un framework MVC sul server era sufficiente per poter gestire una vasta gamma di siti internet, ora tendenza va verso MVC lato server e lato client, cioè:

  • prima. web browser <==> web server + MVC
  • adesso/futuro.  web browser + MVC <==> web server + MVC

Dunque.. perché avere un MVC lato client e lato server?

Perché il web moderno può essere molto più veloce ed interattivo rispetto soluzioni solo lato server. Inoltre la completa separazione dei dati dal markup HTML permette di interagire con un'applicazione web anche in assenza di un browser (leggi sensori o app iPhone).
L'altro punto estremamente interessante è che adottando questo approccio i dati trasferiti su internet sono molto minori rispetto il web attuale perché verranno trasferite solo le "differenze" rispetto quello che  l'utente visualizza e non "pagine intere"

Questo nuovo approccio ha anche degli svantaggi o per lo meno dei punti aperti che vanno trattati con molta cautela.

SEO

Includere dei servizi esterni tramite javascript riduce le capacità di ricerca di google, perché obbliga i motori di ricerca ad analizzare dei link javascript e le loro interazioni invece che pagine HTML intere.

Google ha divulgato delle linee guida per gestire i contenuti all'interno di siti dinamici, ma praticamente i "vecchi" link sono tuttora considerati maggiormente.

Esempio: cercate su google "<username> twitter", i risultati che vengono restituiti continuano and essere del tipo: https://twitter.com/<username> anziché dove porta il redirect cioé https://twitter.com/#!/<username>
..e questo accade nonostante Twitter applichi le specifiche, quindi le URL #! non possono essere considerate definitive 

Il "#!" (leggi hashbang o shebang) significa che si sta visualizzando sempre la pagina index.html ma a uno "stato" diverso e ad ogni interazione l'url fittizia cambia ma vengono cambiate solo aree della pagina e non sostituita tutta completamente. L'hashbang o meglio HTML5 pushstate genera delle url che sono utili al browser per poter andare avanti e indietro, ma digitate manualmente spesso portano a pagine inesistenti, per questo si usa la convenzione #!/mio/percorso per differenziarle dalle url classiche.

Quindi se non volete avere delle pesanti ricadute in termini SEO, dovete duplicare il routing ai contenuti anche lato client o comunque gestire il fallback ad URL classiche.

Duplicazione delle viste HTML e del routing lato client

Indipendentemente dal linguaggio lato server che usate ci sarà un template HTML con dei "buchi" dove mettere i dati presi dalle variabili  e la stessa cosa accade quando si vuole renderizzare un template lato client che non necessariamente ha bisogno di contattare il server per essere mostrato.

In questo caso o si duplica il template lato server e lato client oppure lo si implementa solo lato javascript, ma in questo caso si incorrerà nella potenziale problematica SEO descritta sopra.

Un modo per riciclare lo stesso template sia sul client che sul server è utilizzare un linguaggio di template neutrale (logic-less) e riempirlo quando serve sia da javascript che dal linguaggio lato server.

Stesso discorso per il doppio routing, ovvero la funzionalità che mappa una URL a una risorsa (meglio REST) che può essere accessibile via javascript ma che sarebbe meglio che fosse accessibile con js disabilitato.

Ricapitolando

Per avere una webapp che sia tale, ma anche linkabile e analizzabile come un sito web ci vuole:

browser con (o senza js) o un'applicazione nativa (iOS, Android)

  • Un routing livello js che gestisca l'HTML5 pushState, ad esempio Davis, Spine JS, Backbone, Sammy..
  • Un MVC javascript che gestisca delle risorse più o meno temporanee che hanno bisogno di essere scritte prima o poi sul server (per questa parte Spine JS mi sembra il più pulito, ed è anche scritto in Coffeescript)
  • Un sistema di template per generare HTML partendo da JSON che sarà condiviso col server (quindi non ERB o PHP), ma mustache, handlebars, eco, jquery-tmpl,..

... JSON over HTTP ...

Un web server

  • Un routing lato server che gestisca le chiamate del client in modo coerente sul server (Rails, Sinatra, ..)
  • Un MVC che sia in grado di rispondere con HTML solitamente solo la prima chiamata e successivamente con JSON (Rails, Sinatra, ..)
  • Un sistema di template Logic-less che possa essere renderizzato anche via js. In questo caso mustache, che può essere renderizzato via server tramite poirot, stache, handlebars_assets (che però renderizza il template solo per il client)
  • Un database o storage noSQL, per salvare i dati in modo persistente. 

Giusto per farvi apprezzare questo stack, che in realtà potrebbe essere ricreato con tecnologie analoghe o alternative, ho fatto il porting a Rails 3.1 di questo semplice ma completo esempio creato da Oliver Nightingale. Per maggiori informazioni guardate il sorgente su Rails 3.1, il demo su Rails 3.0 o debuggate le chiamate del demo per vedere effettivamente i dati che transitano.

File interessanti:

routing javascript (app.js)
https://github.com/grigio/notepad/blob/rails3.1.x/app/assets/javascripts/app.js.erb

model javascript
https://github.com/grigio/notepad/blob/rails3.1.x/app/assets/javascripts/models/note.js

routing rails
https://github.com/grigio/notepad/blob/rails3.1.x/config/routes.rb

vista mustache client+server
https://github.com/grigio/notepad/blob/rails3.1.x/app/views/notes/_note_form.html.mustache

variabili lato server disponibili nella vista
https://github.com/grigio/notepad/blob/rails3.1.x/app/views/notes/note_form_view.rb

Spero di avervi incuriosito un po', avete approcci migliori?

Davvero, ci sono tantissime tecnologie open innovative che meriterebbero più spazio (e più tempo per seguirle), proprio per questo stiamo organizzando un evento che si terrà a Torino nel nuovo anno.
Se siete tecnici, professionisti o semplicemente programmatori appassionati, rimanete in ascolto ci sono novità interessanti in arrivo.