$resource para comunicación RESTful en AngularJS

En el post anterior hemos visto cómo se podía hacer una comunicación con un servidor RESTful mediante el objeto $http de AngularJS. Este objeto proporcionaba una interfaz para las llamadas AJAX parecida a la que se puede hacer con JQuery o Prototype.

En realidad referirse a la anterior como comunicación como RESTful era un tanto específica, puesto que se trataba de un caso particular. En realidad eran llamadas AJAX y no tenían por qué hacerse a un servidor RESTful específicamente: cualquiera que admitiera una llamada AJAX valdría.

Por recordar, dentro del controlador teníamos algunas funciones como estas.

$http.get("http://127.0.0.1:5984/dibujo/"+id).success(function(datos)
{
//Operaciones con el objeto JSON datos obtenido de la llamada
});

$http.post("http://127.0.0.1:5984/dibujo", {"e":$scope.elementos,"t":new Date().getTime()}).success(function(datos)
 {
//Operaciones una vez se ha enviado el objeto en formato JSON
 });
<span style="line-height: 1.5em;">

Es decir, llamadas GET y POST indicando la URL directamente, e incluso, si hacía falta, componiendo la URL final con el id a base de concatenación de cadenas de texto. También existían otro tipo de llamadas como DELETE, HEAD o PUT (http://docs.angularjs.org/api/ng.$http).

AngularJS es un framework centrado en facilitar la vida a los programadores, con un nivel de abstracción bastante elevado y la comunicación con un servidor puramente RESTful es una buena candidata a automatizar tareas.

Mediante $resource, AngularJS pone a nuestra disposición objetos para interactuar con un servidor que soporte el protocolo RESTful. Este objeto encapsula los mecanismos de comunicación RESTful, evitando tener que bajar al nivel de hacer llamadas mediante $http. Para que funcione es necesario utilizar el módulo ngResource (ver cómo instalarlo en http://docs.angularjs.org/api/ngResource).

Así pues, usaremos el objeto proporcionado por $resource para representar la comunicación con el servidor para un modelo de datos. En realidad encapsula los datos y le añade además una serie de propiedades o funciones para controlar la comunicación con el servidor.

Si continuamos el ejemplo que vengo usando en este blog de la página de dibujo al pasar el ratón sobre un grid, tenemos que, básicamente, el objeto consistía en dos campos: “e” para mantener un objeto que contiene como métodos las coordeadas de los elementos sobre los que había pasado el ratón y el número de veces que lo había hecho; y “t” para indicar la fecha, en milisegundos en la que se habían salvado los datos.

Analizando la siguiente imagen de DevTools de Chrome, se puede ver que “element” es un objeto devuelto por $resource y que encapsula los datos descritos para el dibujo. Podemos ver:

  •  “e” y “t” como se han descrito. Que son los datos que nos devuelve el servidor y que nos interesa.
  •  “_id” y “_rev” que son el id y la versión del documento tal y como lo proporciona CouchDB (revisar post anteriores para más información).
  •  __proto__ que son las operaciones que se añaden y que permiten la comunicación con el servidor RESTful. Como se puede ver, coinciden con los operadores por defecto.

resource1

 

Por lo tanto, el objeto “element” encapsula por una parte la información obtenida de la llamada, y por otra parte añade las operaciones para la comunicación RESTful. Además añade otros elementos como por ejemplo un $promise para implementar la carga asíncrona de información por la llamada AJAX.

Vamos a ver cómo podemos implementarlo.

En primer lugar hay que inyectar el recurso en el controlador de la aplicación:

app.controller("ctrlDibujo", ["$scope","$http", "$resource", ,function($scope, $http,$resource)

De este modo podremos usar la factoría $resource dentro de nuestro código.

La primera forma es imitando a una llamada XHR normal y corriente. No hace uso de la potencia de $resource pero nos da una idea de su uso. Como se puede ver se indica la dirección del servidor así como la URL completa para cargar un objeto determinado:

var Resultado = $resource('http://127.0.0.1:5984/dibujo/9181ffd10aa47c52e1cee65ce0000195').get();

Esto no es realmente útil. Lo ideal sería poder parametrizar la llamada y poder referirnos con el identificador RESTful. Sería algo así:

var Resultado = $resource('http://127.0.0.1:5984/dibujo/:id', {id:"9181ffd10aa47c52e1cee65ce0000195"}).get();

En este caso se puede ver cómo “:id” será sustituído por el valor de “id” del objeto pasado por parámetro. Para el ejemplo se ha completado de forma manual, pero seguro que sabes cómo asignarle una variable.

En ambos casos el resultado es un objeto que contiene la información devuelta por el servidor más las operaciones que le permiten una sencilla comunicación con el servidor.

Una cosa que llama la atención es la asignación a la variable Resultado. Al tratarse de una llamada asíncrona, AngularJS devuelve un promise cuando se realiza la operación GET de modo que la carga de la información a la variable se realizará cuando sea posible. Por tanto no podemos utilizar posteriormente estos datos en la lógica de negocio. No obstante si necesitamos realizar alguna operación, siempre tenemos la opción de usar las funciones de CallBack:

var Resultado = $resource('http://127.0.0.1:5984/dibujo/:id', {id:"9181ffd10aa47c52e1cee65ce0000195"}).get(function(elemento){//...});

Otra de las formas de utilizar $resource es usando un servicio en la aplicación para luego inyectarlo dentro de nuestro controlador. Por ejemplo:

app.factory('ElementoResource', ['$resource', function($resource){
return $resource('http://127.0.0.1:5984/dibujo/:id',{id:"@_id"});
}]);

No debemos olvidar usar el servicio dentro de nuestro controlador:

app.controller("ctrlDibujo", ["$scope","$http", "$resource", "ElementoResource",function($scope, $http,$resource, ElementoResource)

Dentro del $resource del servicio se ha espeficado que el parámetro “id” se lee del campo “_id” del objeto al que arropa. Esto vendrá perfecto para la comunicación con el servidor CouchDB que usa este valor.

Usarlo es sencillo:

 $scope.objetoResource = ElementoResource.get({id:"9181ffd10aa47c52e1cee65ce0000195"}, function(element, $scope)
 {
element.t++;
element.$save();
 });

En este ejemplo se ha pasado el objeto {id:”9181ffd10aa47c52e1cee65ce0000195″} para indicar qué elemento recuperar; se ha aumentado en 1 el valor de su parámetro “t” y se ha vuelto a grabar. Como se puede ver es algo realmente sencillo de utilizar.

Nótese cómo se ha utilizado el Callback para manipiular el objeto.

También es posible crear un nuevo objeto y comunicarse con el servidor:

var nuevoElemento = new ElementoResource();

nuevoElemento.e = {"a1":12};
nuevoElemento.t = new Date().getTime();

nuevoElemento.$save();

nuevoElemento.t = 100;
nuevoElemento.$save();

En este caso se puede ver cómo se ha creado un nuevo objeto usando el servicio, se le han asignado unas propiedades “e” y “t” y luego se ha salvado con el servidor RESTful. Posteriormente se ha modificado la propiedad “t” asignándole 100 de valor y se ha vuelto a salvar.

Sin usar servicio de por medio también es muy directo su uso, y nos evita mucho trabajo respecto a si usáramos $http

var Elemento = $resource('http://127.0.0.1:5984/dibujo/:id');

var nuevoElemento = Elemento();
nuevoElemento.t=23;
nuevoElemento.$save();
...

En resumen, $resource de AngularJS permite comunicar nuestra aplicación con un servicio RESTful de una manera muy sencilla y eficiente.

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s