API REST desarrollada con Java 17, Spring Boot 3 y MySQL para la gestión de tópicos de un foro.
Este proyecto permite registrar, listar, filtrar, detallar, actualizar y eliminar tópicos, relacionándolos con sus respectivos autores.
Está pensado como un backend práctico para reforzar conceptos de:
- desarrollo de APIs REST
- arquitectura por capas
- persistencia con JPA/Hibernate
- validación de datos
- documentación con Swagger/OpenAPI
- manejo global de errores
- integración con MySQL
ForoHub_Challenge es una API backend orientada a la administración de tópicos dentro de un foro académico o técnico.
Cada tópico contiene información como:
- título
- mensaje
- fecha de creación
- estado
- nombre del curso
- autor asociado
Además, el proyecto implementa:
- validación de datos de entrada
- control de errores HTTP
- filtros por curso y año
- paginación
- documentación automática de endpoints
El propósito de este proyecto es construir una API REST funcional que permita modelar la lógica básica de un foro, aplicando buenas prácticas de desarrollo backend con Spring Boot.
- Java 17
- Spring Boot 3.3.1
- Spring Web
- Spring Data JPA
- Hibernate
- MySQL
- Flyway
- Lombok
- Spring Validation
- Springdoc OpenAPI / Swagger UI
- Maven
- IntelliJ IDEA
El proyecto está organizado por capas para separar responsabilidades:
Contiene los controladores REST que reciben las solicitudes HTTP y devuelven las respuestas.
Contiene la lógica de negocio, entidades, repositorios y DTOs.
Contiene configuraciones generales del proyecto, documentación OpenAPI y manejo global de errores.
- Registrar un tópico
- Listar tópicos paginados
- Listar tópicos ordenados por fecha
- Filtrar tópicos por curso y año
- Obtener un tópico por ID
- Actualizar un tópico existente
- Eliminar un tópico
- Validar que el autor exista antes de registrar
- Evitar registros duplicados con el mismo título y mensaje
- Manejar errores con respuestas HTTP claras
- Documentar la API con Swagger
Representa al autor de un tópico.
Campos principales:
idnombrecorreoElectronicoclave
Representa una publicación dentro del foro.
Campos principales:
idtitulomensajefechaDeCreacionestadonombreDeCursoautor
El estado del tópico puede tomar uno de estos valores:
ENVIADORECIBIDO
- Un autor puede tener muchos tópicos
- Un tópico pertenece a un solo autor
Relación implementada con:
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "autorId")Verifica que la API está funcionando correctamente.
Respuesta esperada:
Hello World!
Registra un nuevo tópico.
Lista tópicos paginados, por defecto 5 registros ordenados por título.
Lista 10 tópicos ordenados por fecha de creación.
Filtra tópicos por nombre de curso y año.
Obtiene el detalle de un tópico específico por ID.
Actualiza un tópico existente.
Elimina un tópico por ID.
{
"titulo": "Problema con Spring Boot",
"mensaje": "No logro conectar mi proyecto con MySQL",
"status": "ENVIADO",
"nombreDeCurso": "Java Spring",
"autorId": 1
}{
"titulo": "Problema con Spring Boot 3",
"mensaje": "Ya pude avanzar, pero necesito actualizar la información",
"nombreDeCurso": "Java Spring Boot"
}Al registrar un tópico, la API valida que:
- el título no esté vacío
- el mensaje no esté vacío
- el estado no sea nulo
- el nombre del curso no esté vacío
- el
autorIdno sea nulo - el autor exista en la base de datos
- no exista ya un tópico con el mismo título y mensaje
El proyecto incluye un manejador global de errores con @RestControllerAdvice.
-
404 Not Found
- cuando no existe un tópico con el ID solicitado
-
400 Bad Request
- cuando faltan campos obligatorios
- cuando el autor no existe
- cuando se intenta registrar un tópico duplicado
Esto mejora la claridad y consistencia de las respuestas de la API.
Archivo application.properties:
spring.application.name=forohub
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=${DATASOURCE_URL:jdbc:mysql://localhost:3306/foroHub}
spring.datasource.username=${DATASOURCE_USERNAME:root}
spring.datasource.password=${DATASOURCE_PASSWORD:P@ssw0rd}
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.jpa.show-sql=true
server.error.include-stacktrace=never
springdoc.api-docs.path=/api-docs- conecta la aplicación a MySQL
- permite sobrescribir credenciales con variables de entorno
- actualiza las tablas según las entidades Java
- muestra el SQL ejecutado por Hibernate
- configura la ruta del JSON OpenAPI
- evita exponer stack traces completos en respuestas HTTP
Antes de ejecutar el proyecto, asegúrate de tener instalado:
- Java 17
- Maven
- MySQL
- IntelliJ IDEA o cualquier IDE compatible con Java/Spring
git clone https://github.com/scarrascoore/ForoHub.git
cd ForoHub_ChallengeCREATE DATABASE foroHub;Asegúrate de que las credenciales configuradas en application.properties coincidan con tu instalación de MySQL.
Por defecto:
- usuario:
root - contraseña:
P@ssw0rd
Si deseas, puedes usar variables de entorno:
DATASOURCE_URLDATASOURCE_USERNAMEDATASOURCE_PASSWORD
Desde IntelliJ IDEA, ejecuta la clase principal:
ForohubApplicationO desde Maven:
mvn spring-boot:runEl proyecto incluye dependencia de Flyway, por lo que la base de datos debe estar correctamente preparada para evitar conflictos entre migraciones y tablas existentes.
Si Flyway detecta un esquema no vacío sin tabla de historial, puede requerirse:
- una base limpia
- configuración de baseline
- o revisar las migraciones del proyecto
Puedes probarla desde:
- Swagger UI
- Bruno
- Insomnia
- Postman
GET /helloComo no hay endpoint para crear autores, puedes insertarlo directamente en MySQL:
INSERT INTO autores (nombre, correoElectronico, clave)
VALUES ('Juan Perez', 'juan@correo.com', '123456');POST /topicosBody:
{
"titulo": "Mi primer tópico",
"mensaje": "Estoy probando mi API",
"status": "ENVIADO",
"nombreDeCurso": "Spring Boot",
"autorId": 1
}GET /topicosGET /topicos/1PUT /topicos/1DELETE /topicos/1El repositorio de tópicos incluye una consulta personalizada para filtrar por curso y año:
@Query("SELECT t FROM Topico t WHERE t.nombreDeCurso = :curso AND FUNCTION('YEAR', t.fechaDeCreacion) = :año")
List<Topico> findByCursoAndAño(String curso, Integer año);Esto permite usar:
GET /topicos/filtrar2?curso=Java Spring&año=2026src
└── main
├── java
│ └── com.aluralatam.forohub
│ ├── controlador
│ │ ├── HelloController
│ │ └── TopicosController
│ ├── domain
│ │ ├── autores
│ │ │ ├── Autor
│ │ │ └── AutorRepository
│ │ └── topicos
│ │ ├── Estado
│ │ ├── Topico
│ │ ├── TopicoRepository
│ │ ├── TopicosService
│ │ └── dto
│ ├── infra
│ │ ├── config
│ │ │ ├── CorsConfiguration
│ │ │ └── OpenAPIConfiguration
│ │ └── errors
│ │ └── ManejadorDeErrores
│ └── ForohubApplication
└── resources
└── application.properties- uso de DTOs para separar entidades y respuestas
- arquitectura organizada por capas
- validación de negocio en el servicio
- manejo global de excepciones
- integración con Swagger/OpenAPI
- configuración CORS habilitada
- integración con MySQL y JPA
- soporte para paginación y filtros
- implementar autenticación con Spring Security y JWT
- crear endpoints para registrar y administrar autores
- restringir CORS en producción
- agregar pruebas unitarias y de integración
- usar
Flywaycomo único responsable del esquema - agregar búsqueda por estado o autor
- implementar roles y permisos
- incorporar soft delete en tópicos
- mejorar la seguridad de contraseñas usando hash
Actualmente, el proyecto funciona como una API CRUD de tópicos, apta para pruebas locales y documentación interactiva. Es ideal como proyecto de aprendizaje, portafolio o challenge técnico para demostrar conocimientos en backend con Spring Boot.
Shelvy Carrasco Oré
- GitHub:
https://github.com/scarrascoore - LinkedIn:
https://linkedin.com/in/shelvycarrascoore
Este proyecto fue desarrollado con fines educativos y de práctica.