Spring Boot y Angular forman un potente tándem que funciona muy bien para desarrollar aplicaciones web con un mínimo de espacio.

Es importante que tengas presente que al formar parte de un tutorial este post es un poco más extenso de lo que solemos publicar, pero te aseguro que te lo vas a disfrutar en cada línea de código.

La aplicación Spring Boot


La funcionalidad de nuestra aplicación web de demostración será bastante simplista. Se limitará a obtener y mostrar una lista de entidades JPA desde una base de datos H2 en memoria, y a persistir las nuevas a través de un simple formulario HTML.

CPU
1 vCPU
MEMORIA
1 GB
ALMACENAMIENTO
10 GB
TRANSFERENCIA
1 TB
PRECIO
$ 4 mes
Para obtener el servidor GRATIS debes de escribir el cupon "LEIFER"

Las dependencias de Maven


Aquí están las dependencias de nuestro proyecto Spring Boot:

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-web</artifactId> 
</dependency>
<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring-boot-starter-data-jpa</artifactId> 
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

Ten en cuenta que hemos incluido spring-boot-starter-web porque lo usaremos para crear el servicio REST, y spring-boot-starter-jpa para implementar la capa de persistencia.

The H2 database version is also managed by the Spring Boot parent.

La clase de entidad JPA


Para crear rápidamente un prototipo de la capa de dominio de nuestra aplicación, vamos a definir una clase de entidad JPA simple, que será responsable de modelar los usuarios:

@Entity
public class User {
    
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;
    private final String name;
    private final String email;
    
    // standard constructors / setters / getters / toString
}

La interfaz UserRepository


Dado que necesitaremos una funcionalidad CRUD básica en las entidades de Usuario, también debemos definir una interfaz UserRepository:

@Repository
public interface UserRepository extends CrudRepository<User, Long>{}

El controlador REST


Ahora vamos a implementar la API REST. En este caso, se trata de un simple controlador REST:

@RestController
@CrossOrigin(origins = "http://localhost:4200")
public class UserController {

    // standard constructors
    
    private final UserRepository userRepository;

    @GetMapping("/users")
    public List<User> getUsers() {
        return (List<User>) userRepository.findAll();
    }

    @PostMapping("/users")
    void addUser(@RequestBody User user) {
        userRepository.save(user);
    }
}

No hay nada inherentemente complejo en la definición de la clase UserController.

Por supuesto, el detalle de implementación que merece la pena destacar aquí es el uso de la anotación @CrossOrigin. Como su nombre indica, la anotación permite compartir recursos entre orígenes (CORS) en el servidor.

Este paso no siempre es necesario, pero dado que estamos desplegando nuestro frontend de Angular en http://localhost:4200, y nuestro backend de Boot en http://localhost:8080 , el navegador denegaría las peticiones de uno a otro.

En cuanto a los métodos del controlador, getUser() obtiene todas las entidades de usuario de la base de datos. Del mismo modo, el método addUser() persigue una nueva entidad en la base de datos, que se pasa en el cuerpo de la petición.

Para simplificar las cosas, hemos omitido deliberadamente la implementación del controlador que activa la validación de Spring Boot antes de persistir una entidad. En producción, sin embargo, no podemos confiar únicamente en la entrada del usuario, por lo que la validación del lado del servidor debería ser una característica obligatoria.

Arrancando la aplicación de Spring Boot


Por último, vamos a crear una clase estándar de bootstrapping de Spring Boot, y a rellenar la base de datos con unas cuantas entidades de usuario:

@SpringBootApplication
public class Application {

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

    @Bean
    CommandLineRunner init(UserRepository userRepository) {
        return args -> {
            Stream.of("John", "Julie", "Jennifer", "Helen", "Rachel").forEach(name -> {
                User user = new User(name, name.toLowerCase() + "@domain.com");
                userRepository.save(user);
            });
            userRepository.findAll().forEach(System.out::println);
        };
    }
}

Ahora vamos a ejecutar la aplicación. Como era de esperar, deberíamos ver una lista de entidades de usuario impresa en la consola al iniciarse:

User{id=1, name=John, email=john@domain.com}
User{id=2, name=Julie, email=julie@domain.com}
User{id=3, name=Jennifer, email=jennifer@domain.com}
User{id=4, name=Helen, email=helen@domain.com}
User{id=5, name=Rachel, email=rachel@domain.com}

La aplicación Angular


Con nuestra aplicación de demostración de Spring Boot en funcionamiento, ahora podemos crear una sencilla aplicación Angular capaz de consumir la API del controlador REST.

En otras ocasiones ya hemos comentado la parte de la instalación de Angular CLI, sin embargo; si tu eres un nuevo lector o quieres repasarla la tocaremos a continuación

Instalación de Angular CLI


Utilizaremos Angular CLI, una potente utilidad de línea de comandos, para crear nuestra aplicación Angular.

Angular CLI es una herramienta muy valiosa ya que nos permite crear todo un proyecto Angular desde cero, generando componentes, servicios, clases e interfaces con sólo unos pocos comandos.

Una vez que hemos instalado npm (Node Package Manager), abriremos una consola de comandos y escribiremos el comando

npm install -g @angular/cli@1.7.4

Eso es todo. El comando anterior instalará la última versión de Angular CLI.

Andamiaje de proyectos con Angular CLI


Podemos generar la estructura de nuestra aplicación Angular desde cero, pero honestamente, esta es una tarea propensa a errores y que consume mucho tiempo que deberíamos evitar en todos los casos.

En su lugar, dejaremos que Angular CLI haga el trabajo duro por nosotros. Así que podemos abrir una consola de comandos, luego navegar a la carpeta donde queremos que se cree nuestra aplicación, y escribir el comando.

ng new angularclient

El nuevo comando generará toda la estructura de la aplicación dentro del directorio angularclient.

El punto de entrada de la aplicación Angular


Si miramos dentro de la carpeta angularclient, veremos que Angular CLI ha creado efectivamente un proyecto completo para nosotros.

Los archivos de aplicación de Angular utilizan TypeScript, un superconjunto tipado de JavaScript que compila a JavaScript plano. Sin embargo, el punto de entrada de cualquier aplicación de Angular es un viejo archivo index.html.

Vamos a editar este archivo:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Spring Boot - Angular Application</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="stylesheet" 
    href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" 
    integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
    crossorigin="anonymous">
</head>
<body>
  <app-root></app-root>
</body>
</html>

Como podemos ver arriba, hemos incluido Bootstrap 4 para poder dar a los componentes de la interfaz de usuario de nuestra aplicación un aspecto más elegante. Por supuesto, es posible elegir otro kit de interfaz de usuario del montón disponible por ahí.

Fíjate en las etiquetas personalizadas <app-root> </app-root>  dentro de la sección <body> . A primera vista, parecen bastante extrañas, ya que <app-root> no es un elemento estándar de HTML 5.

Las mantendremos ahí, ya que  es el selector de raíz que Angular utiliza para renderizar el componente raíz de la aplicación.

El componente raíz app.component.ts


Para entender mejor cómo Angular vincula una plantilla HTML a un componente, vamos a ir al directorio src/app y editar el archivo TypeScript app.component.ts, el componente raíz:

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {

  title: string;

  constructor() {
    this.title = 'Spring Boot - Angular Application';
  }
}

Por razones obvias, no nos sumergiremos en el aprendizaje de TypeScript. Aun así, observemos que el archivo define una clase AppComponent, que declara un campo título de tipo string (en minúsculas). En definitiva, se trata de JavaScript tipado.

Además, el constructor inicializa el campo con un valor de cadena, lo que es bastante similar a lo que hacemos en Java.

La parte más relevante es el marcador de metadatos o decorador @Component, que define tres elementos

  1. Selector: El selector HTML utilizado para vincular el componente al archivo de plantilla HTML.
  2. TemplateUrl:  El archivo de plantilla HTML asociado al componente
    styleUrls - uno o más archivos CSS asociados al componente
    Como era de esperar, podemos utilizar los archivos app.component.html y app.component.css para definir la plantilla HTML y los estilos CSS del componente raíz.
  3. Por último, el elemento selector vincula todo el componente al selector  incluido en el archivo index.html.

El archivo app.component.html


Dado que el archivo app.component.html nos permite definir la plantilla HTML del componente raíz, la clase AppComponent, lo utilizaremos para crear una barra de navegación básica con dos botones.

Si hacemos clic en el primer botón, Angular mostrará una tabla que contiene la lista de entidades de usuario almacenadas en la base de datos. Del mismo modo, si hacemos clic en el segundo, se mostrará un formulario HTML, que podemos utilizar para añadir nuevas entidades a la base de datos:

<div class="container">
  <div class="row">
    <div class="col-md-12">
      <div class="card bg-dark my-5">
        <div class="card-body">
          <h2 class="card-title text-center text-white py-3">{{ title }}</h2>
          <ul class="text-center list-inline py-3">
            <li class="list-inline-item">
              <a routerLink="/users" class="btn btn-info">List Users</a>
                </li>
            <li class="list-inline-item">
              <a routerLink="/adduser" class="btn btn-info">Add User</a>
                </li>
          </ul>
        </div>
      </div>
      <router-outlet></router-outlet>
    </div>
  </div>
</div>

La mayor parte del archivo es HTML estándar, con algunas advertencias que vale la pena señalar.

La primera es la expresión {{ title }}. La doble llave {{ nombre-variable }} es el marcador de posición que Angular utiliza para realizar la interpolación de variables.

Tengamos en cuenta que la clase AppComponent inicializó el campo title con el valor Spring Boot - Angular Application. Así, Angular mostrará el valor de este campo en la plantilla. Del mismo modo, el cambio del valor en el constructor se reflejará en la plantilla.

La segunda cosa a tener en cuenta es el atributo routerLink.

Angular utiliza este atributo para el enrutamiento de las solicitudes a través de su módulo de enrutamiento (más sobre esto más adelante). Por ahora, es suficiente saber que el módulo enviará una petición a la ruta /users a un componente específico y una petición a /adduser a otro componente.

En cada caso, la plantilla HTML asociada con el componente correspondiente se mostrará dentro del marcador de posición .