Servicios REST con Spring MVC y AngularJS

11
41933

Servicios REST con Spring MVC y AngularJS

0. Índice de contenidos.


1. Introducción.

En este tutorial vamos a montar un pequeño proyecto donde vamos a dar de alta un par de servicios REST con Spring MVC y los vamos a consumir desde una aplicación en AngularJS. Los servicios (o recursos) REST se consideran entidades que representan conceptos de negocio. Actualmente se está trabajando mucho para construir en las organizaciones APIs REST que expongan su negocio de forma sencilla para ser consumidos por diferentes aplicaciones. Veremos cómo implementar los recursos REST con Spring MVC y su consumo a través de una aplicación hecha en AngularJS.

Si quieres descargar el código fuente del tutorial pincha aquí.

2. Entorno.

El tutorial se ha realizado con el siguiente entorno:

  • MacBook Pro 15′ (2.4 GHz Intel Core i5, 8GB DDR3 SDRAM).
  • Oracle Java SDK 1.7.0_60
  • Spring Boot 1.1.10.RELEASE
  • Spring MVC 4.0.8.RELEASE
  • AngularJS 1.2.21

3. Configuración del proyecto

Lo primero será crear el proyecto por lo que usaremos Maven para ello. En el pom.xml metemos lo siguiente:


	4.0.0
	com.autentia.tutoriales
	springmvc-angular
	1.0-SNAPSHOT

	
        org.springframework.boot
        spring-boot-starter-parent
        1.1.10.RELEASE
    

    
    	
		   org.springframework.boot
		   spring-boot-starter-thymeleaf
  		
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

Utilizaremos el spring-boot-starter-parent para utilizar las dependencias comunes de un proyecto Spring. También añadimos la dependencia spring-boot-starter-thymeleaf para utilizar el motor de plantillas Thymeleaf ya que en nuestro caso las vistas se construirán en HTML5 y AngularJS.

4. Servicios REST con Spring MVC

Para la prueba de concepto crearemos un API REST con un endpoint que devuelva un listado de películas con la información en formato JSON del título, año del estreno y el nombre del director. También haremos otro endpoint para añadir una película al catálogo desde la página web. El formato y las URLs serían las siguientes:

HTTP GET /films

Respuesta:

[
    {
        title: "12 years a slave",
        year: 2013,
        director: "Steve McQueen"
    },
    {
        title: "Argo",
        year: 2012,
        director: "Ben Affleck"
    },
    {
        title: "The Artist",
        year: 2011,
        director: "Michel Hazanavicius"
    }
]

HTTP POST /films

Petición:

	{
		title: "No Country for Old Men",
		year: 2007,
		director: "Joel y Ethan Coen"
	}

El código que cubre el API REST lo añadimos en la clase FilmsController, para ello la anotamos con @RestController. Esta anotación de Spring MVC proporcionará superpoderes REST a la clase. Los métodos anotados con @RequestMapping y el verbo HTTP correspondiente (GET, POST) se encargarán de representar los endpoints de nuestra API de películas. Es sólo un ejemplo por lo que las películas las meto en una lista que me creo en la propia clase.

package com.autentia.tutoriales;

import java.util.ArrayList;
import java.util.List;

import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping(value = "/films")
public class FilmsController {

	private static final List<Film> DUMMY_FILMS = new ArrayList<Film>();
	
	static {
		DUMMY_FILMS.add(new Film("12 years a slave", 2013, "Steve McQueen"));
		DUMMY_FILMS.add(new Film("Argo", 2012, "Ben Affleck"));
		DUMMY_FILMS.add(new Film("The Artist", 2011, "Michel Hazanavicius"));
		DUMMY_FILMS.add(new Film("The King's speech", 2010, "Tom Hooper"));
		DUMMY_FILMS.add(new Film("The Hurt Locker", 2009, "Kathryn Bigelow"));
		DUMMY_FILMS.add(new Film("Slumdog Millionaire", 2008, "Danny Boyle"));
		DUMMY_FILMS.add(new Film("No Country for Old Men", 2007, "Joel y Ethan Coen"));
	}
	
	@RequestMapping(method = RequestMethod.GET)
	public List<Film> getFilms() {
		return DUMMY_FILMS;
	}
	
	@RequestMapping(method = RequestMethod.POST)
	public void addFilm(@RequestBody @Valid Film film) {
		DUMMY_FILMS.add(film);
	}
}

Automáticamente y sin necesidad de configurar nada Spring MVC se encargará de serializar y deserializar de JSON a Java y viceversa.

La anotación @RequestBody se utiliza para indicar que el objeto film vendrá en el cuerpo de la petición. La anotación @Valid se utiliza para lanzar las validaciones del estándar JSR 303 Bean Validation.

La clase Film es un POJO normal y corriente:

package com.autentia.tutoriales;

import javax.validation.constraints.NotNull;

import org.hibernate.validator.constraints.NotEmpty;

public class Film {

	@NotEmpty
	private String title;
	
	@NotNull
	private Integer year;
	
	@NotEmpty
	private String director;

	private Film() {
		
	}
	
	public Film(String title, Integer year, String director) {
		this.title = title;
		this.year = year;
		this.director = director;
	}

	public String getTitle() {
		return title;
	}

	public Integer getYear() {
		return year;
	}

	public String getDirector() {
		return director;
	}	
}

Con esto tenemos nuestro API Rest preparado. Nos faltarán un par de clases: una para configurar el arranque de la aplicación a través de Spring Boot y la otra para redireccionar a la página de inicio index.html

package com.autentia.tutoriales;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}
}

Para no tener que configurar pesados ficheros XML queda mucho más limpia la configuración de esta manera.

package com.autentia.tutoriales;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
public class AppController {

	@RequestMapping(value = "/", method = RequestMethod.GET)
    String home() {
        return "index";
    }
	
}

Cuando entremos a la URL http://localhost:8080/ nos redirigirá a nuestro index.html.

5. Consumir los servicios REST con AngularJS

Una vez montado todo el API REST sólo nos queda hacer la página donde visualizar el catálogo de las películas. Para ello nos construimos una página index.html.

El código HTML es sencillo. Las directivas de Angular se utilizan para que éste pueda manejar el contenido del HTML y que pueda hacer su magia. Se recoge de la variable ‘films’ que almacena el catálogo con la respuesta del servidor, y se recorre para sacar cada una de los datos de cada película y pintarlo en la página. Debajo aparece el formulario con los campos para añadir una nueva película al catálogo.

<!DOCTYPE html>
<html ng-app="films">
<head>
	<meta charset="UTF-8" />
	<title>Oscar a la mejor película</title>
</head>

<body ng-app="springmvc-angular" ng-controller="FilmsController" ng-init="getFilms()">

	<div class="container" ng-show="films != null">
		<div class="film-info-bottom" ng-repeat="film in films">
			<h4><span> {{film.year}} - {{film.title}} - {{film.director}} </span></h4>
		</div>
	</div>
	
	<div class="form">
		<label for="title">Título:</label>
		<input id="title" ng-model="title" type="text" />
		
		<label for="year">Año:</label>
		<input id="year" ng-model="year" type="number" />
		
		<label for="director">Director:</label>
		<input id="director" ng-model="director" type="text" />
		
		<button id="addBtn" class="btn" ng-click="addFilm()">Añadir película</button>
	</div>
	
	<h4>{{msg}}</h4>
	
	<script src="/wp-content/uploads/tutorial-data/http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular.js"></script>
	<script src="/wp-content/uploads/tutorial-data/http://ajax.googleapis.com/ajax/libs/angularjs/1.2.21/angular-resource.js"></script>
	<script src="/wp-content/uploads/tutorial-data/./js/services.js"></script>
</body>
</html>

En el fichero services.js se añade el código que se encargará de hacer las llamadas al API REST y manejar la respuesta en formato JSON. Mediante el servicio $http.get realizamos la comunicación con el servidor. Le indicamos el endpoint al que debe llamar haciendo una llamada tipo GET de HTTP. Cuando el servidor responde con el resultado de la llamada GET /films se ejecutará la promesa que invoca a la función que se le pasa por parámetro al success en caso de que la respuesta venga con código 200. Dentro del success se almacena el contenido de la respuesta en la variable films. En caso de error se llamará al método error que únicamente muestra un mensaje de error.

var app = angular.module('films', [ "ngResource" ]);

app.controller('FilmsController', [ '$scope', '$http',
                                     
	function($scope, $http) {
		$scope.getFilms = function() {
			$http.get('/films').success(function(data) {
				$scope.films = data;
			});
		}
		
		$scope.addFilm = function() {
			$http.post('/films', 
				{
					title : $scope.title,
					year : $scope.year,
					director : $scope.director
				}
			).success(function(data) {
				$scope.msg = 'Pelicula creada correctamente';
				$scope.getFilms();
			}).error(function(data) {
				$scope.msg = 'Se ha producido un error';
			});
		}
} ]);

Arrancamos el servidor con el comando mvn spring-boot:run y entramos en http://localhost:8080.

6. Conclusiones.

Hemos podido ver lo sencillo que se vuelve el desarrollo web cuando utilizas determinada tecnología que está especialmente pensada para facilitar el desarrollo a los programadores. Tanto AngularJS como Spring MVC son sencillos de utilizar y casi no tienen configuración por lo que con pocas líneas tienes la funcionalidad lista.

Tanto para pequeñas pruebas de concepto como grandes proyectos con cientos de recursos REST esta combinación es perfectamente posible.

Si quieres descargar el código fuente del tutorial pincha aquí

Espero que te haya sido de ayuda.

Un saludo.

Juan

11 COMENTARIOS

  1. hola oye me gustaría saber como validas del lado del servidor
    como muestras el error en pantalla gracias ojala y pudieras ayudarme

  2. Groso! Muy bue aporte. Lo voy a usar tal cual para arrancar con angular y servicios REST.
    Solo que voy a deployar en un Tomcat es lugar de Spring-boot :D.
    Gracias!

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad