Curso de Spring Boot
En este capítulo construiremos un proyecto real completo utilizando todo lo aprendido en el curso.
El objetivo es crear una API REST profesional con:
- Spring Boot
- PostgreSQL
- JWT
- DTOs
- validación
- Swagger
- arquitectura limpia
Este proyecto servirá como plantilla para aplicaciones reales.
20.1 Descripción del proyecto
Crearemos un sistema de gestión de cursos.
Funcionalidades:
1usuarios 2registro 3login 4crear cursos 5listar cursos 6matricular usuarios
Arquitectura:
1Frontend 2 ↓ 3API REST 4 ↓ 5Spring Boot 6 ↓ 7PostgreSQL
20.2 Estructura del proyecto
1com.example.courseapp 2 3config 4controller 5service 6repository 7entity 8dto 9security 10exception
20.3 Entidades
Usuario
1@Entity 2public class User { 3 4 @Id 5 @GeneratedValue 6 private Long id; 7 8 private String username; 9 10 private String email; 11 12 private String password; 13 14}
Curso
1@Entity 2public class Course { 3 4 @Id 5 @GeneratedValue 6 private Long id; 7 8 private String title; 9 10 private String description; 11 12}
Matriculación
1@Entity 2public class Enrollment { 3 4 @Id 5 @GeneratedValue 6 private Long id; 7 8 @ManyToOne 9 private User user; 10 11 @ManyToOne 12 private Course course; 13 14}
20.4 Repositories
1@Repository 2public interface UserRepository extends JpaRepository<User,Long> { 3 4 Optional<User> findByEmail(String email); 5 6}
1@Repository 2public interface CourseRepository extends JpaRepository<Course,Long> { 3 4}
1@Repository 2public interface EnrollmentRepository extends JpaRepository<Enrollment,Long> { 3 4}
20.5 DTOs
Crear usuario
1public class RegisterDTO { 2 3 @NotBlank 4 private String username; 5 6 @Email 7 private String email; 8 9 @Size(min=6) 10 private String password; 11 12}
Crear curso
1public class CourseDTO { 2 3 private Long id; 4 5 private String title; 6 7 private String description; 8 9}
20.6 Servicio de usuarios
1@Service 2public class UserService { 3 4 private final UserRepository repository; 5 6 public UserService(UserRepository repository) { 7 this.repository = repository; 8 } 9 10 public User register(RegisterDTO dto) { 11 12 User user = new User(); 13 14 user.setUsername(dto.getUsername()); 15 user.setEmail(dto.getEmail()); 16 user.setPassword(dto.getPassword()); 17 18 return repository.save(user); 19 20 } 21 22}
20.7 Servicio de cursos
1@Service 2public class CourseService { 3 4 private final CourseRepository repository; 5 6 public CourseService(CourseRepository repository) { 7 this.repository = repository; 8 } 9 10 public List<Course> getCourses() { 11 return repository.findAll(); 12 } 13 14}
20.8 Controller de usuarios
1@RestController 2@RequestMapping("/users") 3public class UserController { 4 5 private final UserService service; 6 7 public UserController(UserService service) { 8 this.service = service; 9 } 10 11 @PostMapping("/register") 12 public User register(@Valid @RequestBody RegisterDTO dto) { 13 14 return service.register(dto); 15 16 } 17 18}
20.9 Controller de cursos
1@RestController 2@RequestMapping("/courses") 3public class CourseController { 4 5 private final CourseService service; 6 7 public CourseController(CourseService service) { 8 this.service = service; 9 } 10 11 @GetMapping 12 public List<Course> getCourses() { 13 14 return service.getCourses(); 15 16 } 17 18}
20.10 Matricular usuario en curso
1@PostMapping("/enroll") 2public Enrollment enroll(@RequestParam Long userId, 3 @RequestParam Long courseId) { 4 5 User user = userRepository.findById(userId).orElseThrow(); 6 Course course = courseRepository.findById(courseId).orElseThrow(); 7 8 Enrollment enrollment = new Enrollment(); 9 10 enrollment.setUser(user); 11 enrollment.setCourse(course); 12 13 return enrollmentRepository.save(enrollment); 14 15}
20.11 Seguridad JWT
Endpoint login.
1@PostMapping("/login") 2public String login(@RequestBody LoginDTO dto) { 3 4 User user = repository.findByEmail(dto.getEmail()) 5 .orElseThrow(); 6 7 if(user.getPassword().equals(dto.getPassword())) { 8 9 return jwtService.generateToken(user.getEmail()); 10 11 } 12 13 throw new RuntimeException("Credenciales inválidas"); 14 15}
20.12 Documentación Swagger
Añadimos dependencia:
1<dependency> 2 <groupId>org.springdoc</groupId> 3 <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> 4 <version>2.5.0</version> 5</dependency>
Acceso:
1http://localhost:8080/swagger-ui.html
20.13 Base de datos
Configuración:
1spring.datasource.url=jdbc:postgresql://localhost:5432/courseapp 2spring.datasource.username=postgres 3spring.datasource.password=1234 4 5spring.jpa.hibernate.ddl-auto=update
20.14 Flujo completo
Registro:
1POST /users/register
Login:
1POST /users/login
Listar cursos:
1GET /courses
Matricular usuario:
1POST /courses/enroll
20.15 Arquitectura final
1Controller 2 ↓ 3Service 4 ↓ 5Repository 6 ↓ 7Database
Con componentes adicionales:
1DTO 2Security 3Validation 4ExceptionHandler 5Swagger