Conectar Angular con Spring Boot es el paso que convierte dos tecnologías independientes en una aplicación full stack completa. Es el stack que usan la mayoría de empresas con Java en el backend: una API REST en Spring Boot y un frontend en Angular que la consume. En este artículo te explico cómo hacerlo desde cero, paso a paso, con código real.
Si aún no tienes claro qué es cada tecnología por separado, te recomiendo leer primero qué es Angular y qué es Spring Boot antes de continuar.
Cómo funciona la arquitectura Angular + Spring Boot
La idea es simple: Spring Boot actúa como servidor backend y expone una API REST. Angular actúa como cliente frontend y hace peticiones HTTP a esa API para obtener y enviar datos.
Durante el desarrollo, ambos corren en servidores separados:
- Spring Boot:
http://localhost:8080 - Angular:
http://localhost:4200
El problema es que el navegador bloquea por defecto las peticiones entre dominios diferentes. Eso se llama CORS (Cross-Origin Resource Sharing) y es lo primero que tienes que configurar.
Paso 1: configurar CORS en Spring Boot para conectar Angular
Sin configurar CORS, Angular no podrá hablar con tu API. En cuanto hagas la primera petición, verás un error en la consola del navegador parecido a este:
Access to XMLHttpRequest at 'http://localhost:8080/api/usuarios'
from origin 'http://localhost:4200' has been blocked by CORS policy.
La solución más limpia en Spring Boot es crear una clase de configuración global. Puedes consultar la documentación oficial de Spring sobre CORS para ver todas las opciones disponibles.
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class CorsConfig {
@Bean
public WebMvcConfigurer corsConfigurer() {
return new WebMvcConfigurer() {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/api/**")
.allowedOrigins("http://localhost:4200")
.allowedMethods("GET", "POST", "PUT", "DELETE")
.allowedHeaders("*");
}
};
}
}
Con esto permites que Angular en localhost:4200 pueda llamar a cualquier endpoint bajo /api/ con los métodos HTTP más comunes.
⚠️ Ojo en producción: cambia
allowedOriginspor la URL real de tu frontend. Nunca uses*en producción si tu API maneja datos sensibles.
Paso 2: crear el endpoint REST en Spring Boot
Para el ejemplo vamos a usar una entidad Producto sencilla. Primero la entidad JPA:
@Entity
@Table(name = "productos")
public class Producto {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String nombre;
private Double precio;
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getNombre() { return nombre; }
public void setNombre(String nombre) { this.nombre = nombre; }
public Double getPrecio() { return precio; }
public void setPrecio(Double precio) { this.precio = precio; }
}
El repositorio JPA:
@Repository
public interface ProductoRepository extends JpaRepository<Producto, Long> {
}
Y el controlador REST que expone los endpoints:
@RestController
@RequestMapping("/api/productos")
public class ProductoController {
@Autowired
private ProductoRepository repo;
@GetMapping
public List<Producto> getAll() {
return repo.findAll();
}
@PostMapping
public Producto create(@RequestBody Producto producto) {
return repo.save(producto);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> delete(@PathVariable Long id) {
repo.deleteById(id);
return ResponseEntity.noContent().build();
}
}
Arranca Spring Boot con ./mvnw spring-boot:run y verifica que la API responde en http://localhost:8080/api/productos. Deberías ver un array JSON vacío [] si la base de datos está vacía.
Paso 3: consumir la API desde Angular con HttpClient
Para conectar Angular con Spring Boot necesitas activar HttpClient en tu proyecto. Añádelo en app.config.ts:
import { ApplicationConfig } from '@angular/core';
import { provideHttpClient } from '@angular/common/http';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(routes),
provideHttpClient()
]
};
Ahora crea un servicio para encapsular todas las llamadas a la API:
ng generate service servicios/producto
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
export interface Producto {
id?: number;
nombre: string;
precio: number;
}
@Injectable({
providedIn: 'root'
})
export class ProductoService {
private apiUrl = 'http://localhost:8080/api/productos';
constructor(private http: HttpClient) {}
getAll(): Observable<Producto[]> {
return this.http.get<Producto[]>(this.apiUrl);
}
create(producto: Producto): Observable<Producto> {
return this.http.post<Producto>(this.apiUrl, producto);
}
delete(id: number): Observable<void> {
return this.http.delete<void>(`${this.apiUrl}/${id}`);
}
}
Paso 4: mostrar los datos en el componente Angular
Crea un componente para mostrar la lista de productos:
ng generate component componentes/lista-productos
El TypeScript del componente:
import { Component, OnInit } from '@angular/core';
import { ProductoService, Producto } from '../../servicios/producto.service';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-lista-productos',
standalone: true,
imports: [CommonModule],
templateUrl: './lista-productos.component.html',
styleUrls: ['./lista-productos.component.css']
})
export class ListaProductosComponent implements OnInit {
productos: Producto[] = [];
cargando = true;
error = '';
constructor(private productoService: ProductoService) {}
ngOnInit(): void {
this.productoService.getAll().subscribe({
next: (data) => {
this.productos = data;
this.cargando = false;
},
error: (err) => {
this.error = 'Error al cargar los productos. ¿Está Spring Boot arrancado?';
this.cargando = false;
}
});
}
}
Y la plantilla HTML usando la sintaxis moderna de Angular con @if y @for:
<div class="lista-productos">
<h2>Lista de productos</h2>
@if (cargando) {
<p>Cargando productos...</p>
}
@if (error) {
<p class="error">{{ error }}</p>
}
@for (producto of productos; track producto.id) {
<div class="producto-card">
<h3>{{ producto.nombre }}</h3>
<p>{{ producto.precio | currency:'EUR' }}</p>
</div>
}
</div>
Variables de entorno: prepara Angular para producción
Tener la URL de la API hardcodeada en el servicio está bien para desarrollo, pero cuando despliegues necesitas apuntar a otra URL. En src/environments/environment.ts:
export const environment = {
production: false,
apiUrl: 'http://localhost:8080/api'
};
En src/environments/environment.prod.ts:
export const environment = {
production: true,
apiUrl: 'https://tu-api.com/api'
};
Y en el servicio, usa la variable en vez de la URL directa:
import { environment } from '../../environments/environment';
private apiUrl = `${environment.apiUrl}/productos`;
Errores más comunes al conectar Angular con Spring Boot
Estos son los errores que vas a ver sí o sí la primera vez:
❌ Error de CORS
Causa: Spring Boot no tiene configurado el origen de Angular. Solución: revisa la clase CorsConfig y asegúrate de que el origen coincide exactamente con la URL de Angular, incluyendo el puerto.
❌ 404 en los endpoints
Causa: Spring Boot no está arrancado o el @RequestMapping es incorrecto. Solución: prueba la URL directamente en el navegador o con Postman antes de llamarla desde Angular.
❌ HttpClient no está disponible
NullInjectorError: No provider for HttpClient!
Solución: añade provideHttpClient() en el array de providers de app.config.ts. Es el error más típico al empezar.
❌ Los datos llegan como undefined
Causa: la interfaz TypeScript no coincide con el JSON que devuelve Spring Boot. Comprueba que los nombres de los campos son exactamente iguales en ambos lados.
Resumen: cómo conectar Angular con Spring Boot
Para conectar Angular con Spring Boot necesitas seguir estos pasos: configurar CORS en Spring Boot para permitir peticiones desde Angular, crear los endpoints REST en el backend, activar HttpClient en Angular y crear un servicio que encapsule las llamadas a la API. Con eso tienes la base de cualquier aplicación full stack con este stack.
Si quieres seguir aprendiendo, el siguiente paso es añadir autenticación con JWT a tu API de Spring Boot y gestionarlo desde Angular. Lo veremos en el próximo artículo.