Esto es un pequeño codekata para montar un proyecto Spring Boot que simplemente sirva unos ficheros estáticos. Estos ficheros estáticos podrían ser una aplicación sencilla en HTML, CSS y JavaScript.. o algo más elaborado usando por ejemplo Angular, React, Vue..
De igual manera que en este post servimos unos ficheros estáticos a un navegador web, podríamos tener en el frontend una aplicación de móvil, un programa de escritorio o cualquier otro sistema informático capaz de conectarse al proyecto.
Vamos al grano.. 😉
Generando un proyecto esqueleto
Como en los últimos posts sobre Spring Boot, te vengo invitando a que te instales el CLI de Spring Boot. De todas formas los IDEs más usados vienen con ayudas para generar estos inicios de proyecto. Pero siguiendo la vieja usanza de ir a un terminal, podemos listar las principales dependencias por pantalla así:
spring init --list
..y veremos una descripción de cada dependencia disponible con el CLI:
Una alternativa es usar el Spring Initializr y descargar manualmente el nuevo proyecto. Volviendo al codekata en línea de comandos, podemos hacer algo como lo siguiente:
spring init -d=web,devtools spring-boot-serving-static-files
..si todo ha ido bien se tiene que ver algo como lo siguiente:
Creando unos ficheros estáticos, el frontend
Ahora ya tenemos un esqueleto de proyecto. Ya tenemos todo lo necesario para lanzar el programa, y tendremos un servidor web embebido, sirviendo los ficheros del directorio src/main/resources/public/.
No existen ficheros estáticos por defecto, así que podemos crear un index.html en el directorio src/main/resources/public/, y lo servirá al navegador. Podemos lanzar el proyecto desde línea de comando así:
mvn spring-boot:run
..y si todo ha ido bien, tenemos que poder ir al navegador a la URL http://localhost:8080/ y veremos algo como lo siguiente:
Empaquetando todo en un .jar y desplegando en desarrollo o producción
Para esto sólo hay que hacer el instalador, con Maven que viene por defecto. Hay que lanzar el siguiente comando:
mvn install
O mejor si estamos probando varias veces, conviene limpiar lo que podamos haber compilado antes:
mvn clean install
Como no hemos tocado ninguna configuración, esto generará el compilado .jar de Java, que podremos entonces lanzarlo desde línea de comandos así:
java -jar target/spring-boot-serving-static-files-0.0.1-SNAPSHOT.jar
Con este .jar ya podemos ir a los servidores a instalar el programa.
Sirviendo contenido desde el backend al frontend
Lo siguiente entonces es servir contenido dinámico. Esto se hace igual con Java usando Spring Boot, con Python usando Django, con PHP usando Symfony, etcétera.. La idea es que enviamos al navegador el frontend, que va a ser un programa estático. El HTML, CSS y JavaScript no va a cambiar, se envía en el inicio, al navegador, siempre el mismo frontend. Pero el contenido que visualiza este frontend, durante la sesión del visitante con la web, sí que va a cambiar, en función a lo que se le sirve desde el backend.
Entendiendo esto, se comprende cómo funcionan todo este tipo de arquitecturas de proyectos. El frontend pasa a ser un proyecto totalmente independiente del backend, que interacciona con el servidor mediante endpoints.
Por ejemplo, podríamos editar el src/main/resources/public/index.html, para que muestre algo de contenido dinámico, obtenido al vuelo desde el backend de Spring Boot. Este index.html contiene todo el frontend que no va a cambiar, siempre es igual para todos los usuarios. Pero con cada nuevo visitante tendrá un contenido distinto, porque se visualiza lo que se devuelve dinámicamente desde Java Spring Boot en el endpoint /get-some-dynamic-content:
<!DOCTYPE html>
<html lang="es">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Frontend de pruebas</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<p>Esto es un fichero para crear un frontend de pruebas.</p>
<div id="txt-dynamic-content-from-the-backend"></div>
<script>
$(document).ready(function() {
$.ajax({
method: 'GET',
url: '/get-some-dynamic-content',
success: function(response) {
$('#txt-dynamic-content-from-the-backend').html(response);
}
})
});
</script>
</body>
</html>
Y un fichero src/main/java/com/example/springbootservingstaticfiles/infrastructure/http/MainController.java, que es el backend, que recibirá las peticiones del frontend:
package com.example.springbootservingstaticfiles.infrastructure.http;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class MainController {
@GetMapping("/get-some-dynamic-content")
public String getSomeDynamicContent() {
return "Some dynamic content using a random number: " + Math.random();
}
}
Si volvemos de nuevo al navegador tenemos que ver algo parecido a lo siguiente:
Recapitulando, vemos que en la raíz del proyecto cargamos el fichero estático index.html que no cambia en toda la ejecución. Este fichero index.html podría ser una aplicación Angular, React, Vue, etcétera. Desde este frontend hacemos entonces las peticiones que se necesiten al backend, usando los métodos GET, POST, PATCH, DELETE.. en este caso un GET a /get-some-dynamic-content. Y finalmente se encarga el frontend de pintar los datos en pantalla.
A partir de aquí ya es suma y sigue, con las tecnologías que tengamos entre manos..