backbone.js + restful con epiphany + fuelUX datagrid + Bootstrap: Parte 1 Resftul

Pues bueno, la nueva aventura es con estas 3 cosas.
Durante años he manejado mi propia libreria de paginación y visualizción vía web, cuando inicie con esto el
concepto de "ajax" no existia y solo habia escasa documentacion de httpRequest en javascript, Jquery algo que no existia y todavía el DOM era mágina negra, por lo tanto, haciendo una extención de aquella aplicación a algo más moderno, me puse a investigar. 

El objetivo inicial, debido a que se maneja mucha información es en manejar un "browser" paginado, esto es del o más normal, algo que hace uno desde la época de dbBase, mostrar continuidad de datos, y uno de los problemas de la paginación de datos es simpre que cargar para mostrar. El objetivo de la paginación es mostrar y tener en memoria lo mínimo posible.

Las bases de datos ofrecen vistas las cuales nos permite filtrar lo que queremos mostrar, con el fin de que los datos sean concisos. En aplicaciones con mucho manejo de datos hacia un solo cliente, esto es importante, por que  si no paginamos bien, podemos o sobrecargar la base de datos de transferencias inútiles o saturar la computadora con ifnormación inutil, además de esto ,la paginación de toda la información siempre es inútil, casi nadie se va de pantalla por pantalla de 10-20-50 entradas viendo para cubrir el total de las n-mil entradas, pero siempre, siempre hay algún maldito enfermo, y es por ellos que hay que poner... paginación. 

En fin, los "datagrids" vía web, nunca han sido o habían sido como los que vemos en aplicaciones de escritorio, donde practicamente unes la tabla con un modelo y le anexas los datos y voilá, así que queria algo así, pero en javascript, asi que vamos a Google y buscamos por datagrid javascript load ajax content; Salen un buen de opciones, pero en mi caso era por que queria usar "bootstrap" por que toda la aplicación mi idea es que este "bootstrapeada" por quel diseño responsivo y para que al diseñarlo con bootstrap automagicamente me quede funcional para celulares, tabletas, y cualquier otro dispositivo (sí aja)...

Total, que los datagrids que cumplian con este requerimeinto, uno era el bbGrid su implementación es muy sencilla y le tienes que ofrecer una colección de datos de backbone.js y hace todo el truco, por lo menos eso es lo que prometía, pero sin embargo, ahora hace mencion de colección y de backbone.js, oh oh...  comenzamos con la "odisea" de actualización y tambien me encontre con FuelUX

Backbone implementa un modelo MVC (Model Viewer Controller) basado en javacript, sin embargo yo pensaba MVC? pero que C? vía web? controller? que tipo de aberración es eso? dejar que manipulen datos en el front end? Pfffft... no por favor... pero bueno, leyendo un poco más, resulta que Backbone.js implementa la parte del C para hablar principalmente con servicios Restful, oh oh... restful? Y eso qué es?... pues resulta que es una forma de establecer una API, aprovechando el protocolo http de get/post/put/delete... Get obtienes datos, Post agregas datos, Put, modificas datos, Delte, borras, totalmente mapeado al CRUD y "URI" friendly. 

Quizá esta parte del URI friendly fué lo que me sedujo, así que ahora, habia que investigar sobre API's restful, por que ahora el "chiste" de Restful es que todo lo pasas por un solo punto "gateway" y el gateway
procesa las rutas y ejecuta lo que tenga que ejecutar, cuando estaba leyendo todo eso, me sonaba a expresiones regulares y mod_rewrite, que pensando  adicionalmente, significaba que integrar restful con mod_security para implementar los servicios con algo de OWASP, todo parecía hermoso, así que, de querer implementar un datagrid con bootstrap ahora tenia que investigar:

La implementación del backend fué lo primero que me puse a investigar, resful habla de un montón de cosas que esta estandarizado (si ajá) y mil maravillas más y que esta diseñado para hablar JSON, normalmente yo habia estado trabajando con WDDX que es como... humm.. un sobre para el XML... pero ya ven, que XML es gordo que difícil de parsear que los DTD que se convierten en DDT para el desarrollador que lo "in" para el web es JSON, venga pues, ya tenemos tiemo trabajando con JSON y WDDX en forma indistinta, así que... total...  que, para no hacer más largo el mensaje, en base a esta página que concentra información de varios Frameworks Resftul me puse a leer, pero para ahorrarles el trabajo: 

  • DAVE  is dead... ni se acerquen, esta... muerto, me escuchan. Muerto.
  • FRAPI Oh... tiene un sitio bonito... con eso de que los frameworks son para que los no desarrolladores desarrolen, ah sí? pues FUCK YOU, no encontre náda rápido para ponerme a trabajar... así que... adios.
  • Recess otro sitio bonito... maalo, click en getting started, tutorials FUCK YOU! VIDEO? Que qué!? mucho voy a dar cut and paste a EL VIDEO?! olvidalo otro "framework" orientado a programar para los no programadores, tengo prisa, ok? 
  • SLIM y TONIC me\mostraron\una\sintaxis\que\me\dio\miedo y los mandé directo a la fregada, diagonales en los nombres declarativos de una clase?! NO THANKS. Soy old school... 
  • Zend Rest Server como la gran marca, el gran framework, que tiene interconecciones con otras partes del framework y... su ejemplo pésimo así que no gracias 
  • Epiphany este fué el bueno. Por qué? por que cumple lo que promete: Fast.Easy.Clean.RESTful
Lo primeroa entender de resful, era la parte de "ruteo", Epiphany implementa un modelo MVC (oh no, no again!) pero la verdad, es sumamente sencillo. Solo hay que incluir un Epi.php inicializar los "modulos" definir rutas y listo, ahora durante toda la investigación algo que me molestaba es que solo ponen ejemplo de get, nunca de post, sin embargo los ejemplos de epiphany fueron ilustrativos. Solo necesité el ejemplo del index para entender.

Por cierto, como la ida de resftul es todo pasarlo por un mismo punto, hay que habilitar el mod_rewrite decirle eso al apache; El ejemplo que te dan para configurar el apache es:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\?*$ index.php?__route__=/$1 [L,QSA]

Que NO FUNCIONA!, en esto es donde más me tarde. Una vez que refresqué a fuerzas las skillz de mod_rewrite y habilité debugs mi "Rewrite" lo deje así:
RewriteEngine on
RewriteEngine /var/log/apache/rewritelog.log
RewriteLogLeve 2
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\?*$ /api.php?__route__=/$1 [L,QSA]

Notese que todo lo mando en /api.php en vez de index.php, pero eso fué por que los index.php si me interesa usarlos por convencionalismo. Nota, el problema es el RewriteRule que apunta a index.php, el problema es que debe de apuntar a /index.php 

Una vez hecho esto, pude entender lo que se refieren con URI Friendly de Restful. En vez de tener archivos y archivos y partecitas por todo lados, las "rutas" te dicen que hacer. Resftul mapea un URL a un Objeto que ejecuta algo, y para esto, EPI, simplemente "funciona". 
Para inicializar EPI solo se requiere incluir el Epi.php
include_once 'Epi.php';
Epi::setPath('base', '/include/epi');
Epi::init('route');
El setPath es para decirle donde estan sus demas archivos y el init es para inicializar el "ruteador" de rest.

Ahora, declaramos una ruta "get" para el url http://localhost/sample 
getRoute()->get('/sample/', array('prueba', 'sample'));
getRoute()->get('/sample/index.php', array('prueba', 'sample'));
getRoute()->run();
Declare /sample y /sample/index.php por que el apache, al mandar tú un get "al index" es decir que el URI termine con /, automágicamente lo substitute con index.php y si no declaras esa ruta, REST mostrara una excepción. 
El segundo argumento es array("nombre de la clase", "nombre del metodo a invocar"); 
Así que Epi, cuando escribas en el navegador http://localhost/sample/ invocará el método público estático prueba::sample(), por lo tanto "para que jale" solo hay que declarar:
class prueba
{
  static public function sample()
  {
    echo 'Fuck yeah! I'm resting';
  }
}

Así de simple, claro que sin paso de parámetros, la verdad, esta madre no sirve mucho, pero allí es lo que me convenció de RESTful, el paso de parámetros se hace con expresiones  regulares. Lo siguiente que hize fue ver lo del paso de parámetros y la documentacion dice que es en base a rutas con expresiones regulares, así que queria hacer un método rápido que me recibiera 2 parametros, un numero para contar del 1 al N, y un color para pintar el texto de ese color y ademas "por mis... poderes de diseño de API", queria que el formato fuera:
http://localhost/sample/numero/XX/color/COLOR 
Y eso se define en el EPI así:
getRoute()->get('/sample/numero/(\d+)/color/(\w+)', array('prueba', 'sample'));
getRoute()->run();
Y mi clase, muy inocente y a la "primera" lo que pense fue, pues a ver si jala siguiendo una lógica de programador e hice:
class prueba
{
  static public function sample($numero=0, $color="back")
  {
    for($i=0;$i<$numero;$i++)
print "$i\n";
  }
}
Y... funcionó; http://localhost/sample/numero/10/color/red me pinto del 0 al 9 en color rojo. Con esto prácticamente estaba validadno que "numero" sea numero entero positivo... UUuuUUUuu.. me gustó. 
Y con esto me decidí ha hacer la priemra parte de mi paginador, la parte del backend con una ruta:
http://uri/sync/clientes/fromid//offset/ siendo id y offset numericos positivos. Me decidí por este formato de API, por que era fácil para establecer un query sobre el id, con un limit, la razón de esto es la siguiente:

Supongamos que tenemos una tabla con 70,000 (setentamil) de registros, con una estructura id,nombre,fechaIngreso. Si no paginaba, 70mil registros "de a madrazo" generaria 2 cosas:
  1. Tráfico a lo idiota de la servidor web a el navegador.
  2. Consumo de memoria a lo idiota en el navegador.
Y eso en mi diccionario de desarrollo son "no, no, bu! bu!" por lo tanto, lo que iba a seguir era unir mi "paginador rest" con la "coleccion backbone" para asociarla al "datagrid bbgrid" y terminaría. 
Qué lejos estaba aún de mi objetivo y yo no lo sabía. Pero por hoy es suficiente, le sigo en otra publicación.


No hay comentarios.:

// Cookie consent