@drawohara¡me encanta esto! << haga clic en mí 🐛 🫖 🧚
/angularjs-service-rails-api
publicado el: 2014-06-10

Recientemente tuve que sumergirme en AngularJS en un sitio de Rails que estábamos construyendo para un cliente. Además del contenido de la página, el cliente tiene ciertas páginas que muestran titulares que enlazan a fuentes externas pero que se extraen en nuestro stack de Rails a través de una tarea rake que se ejecuta periódicamente. El sitio debe ser almacenado en caché intensamente a través del uso de una CDN, como CloudFront, pero para mantener los titulares actualizados, utilizamos AngularJS (porque el cliente estaba familiarizado con él, lo que facilitaba su mantenimiento) para consultar directamente el stack de rails sobre los últimos titulares.

Esto requirió hacer las cosas de manera transversal, ya que el dominio del sitio apuntaría a CloudFront. No había escrito una API de Rails que devolviera JSONP ni un servicio de AngularJS antes, así que tuve que explorar un poco y esto es lo que funcionó para mí. (También puedes leer el gist.)

Nota: Si no estás familiarizado con JSONP, esto no tendrá mucho sentido. Lee esto.

Servicio de AngularJS

AngularJS tiene el concepto de servicios, que son solo singletons que se pueden usar donde sea necesario. En nuestro caso, puedes pensar en nuestro servicio de titulares como el cliente de la API de titulares que envuelve nuestras llamadas JSONP en una sintaxis más simple y centralizada. AngularJS proporciona algunos servicios por defecto, pero puedes escribir los tuyos propios. De hecho, podríamos haber usado el servicio $resource integrado en lugar de escribir el nuestro, sin embargo, tuve algunos problemas para que JSONP funcionara y quería entender mejor los componentes de bajo nivel de AngularJS, así que escribí el mío:

angular.module('app')
  .factory('HeadlineService', ['$http',
    function($http) {
      'use strict';

      var BASE_URL = "<%= [App.settings.api_base_url, '/services/headlines'].join %>",
          CALLBACK_STRING = "?callback=JSON_CALLBACK";

      return {
        getHeadlines: function(){
          return $http.jsonp(BASE_URL + CALLBACK_STRING)
        },
        getHeadlineForId: function(id){
          return $http.jsonp(BASE_URL + "/" + id + ".json" + CALLBACK_STRING)
        }

    }
  ]);

El servicio anterior usa el servicio $http integrado, que simplemente proporciona un wrapper AJAX, para hacer solicitudes a nuestro backend de rails para obtener titulares. Algunas cosas a tener en cuenta:

Controlador de AngularJS

Con nuestro HeadlinesService construido, ahora podemos usar las 2 funciones que devuelve en nuestra aplicación de AngularJS:

angular.module('app')
  .controller('HeadlinesCtrl', ['$scope', 'HeadlineService',
    function($scope, HeadlineService) {
      'use strict';
 
      HeadlineService.getHeadlines().success(function(data, status, headers, config){
        $scope.headlines = data;
        
        HeadlineService.getHeadlineForId(data[0].id).success(function(data){