Como hacer un CRUD en Spring Boot + JPA + PostgreSQL + API REST

En este tutorial te explico como hacer un API REST completo desde cero usando Spring Boot y PostgreSQL como base de datos.

Empecemos por lo basico para este tutorial. Necesitaremos:

  • PG Admin
  • STS 4 (Spring Tool Suite 4)
Tabla de contenido
  1. Como crear un CRUD en Spring Boot
    1. Estructura del proyecto
    2. Tutorial paso a paso

Como crear un CRUD en Spring Boot

Spring es una de las herramientas más usadas para crear backends. Aunque se puede usar cualquier tipo de base de datos, para este tutorial vamos a usar PostgreSQL.

Primero veamos la estructura del proyecto.

Estructura del proyecto

No te preocupes si aun no entiendes del tema, pues iremos paso a paso construyendo cada paquete y casa clase.

En la industria del desarrollo de software, la mayoria de proyectos tienen esa estructura:

  • Model: modelo de los objetos a guardar en base de datos.
  • Repository: repositorio encargado de la persistencia de los objetos del modelo.
  • Service: es la implementacion o la invocación de cada repositorio, pues aunque se puede hacer directamente en el REST, es más estético y limpio crear un service.
  • Rest: es la clase encargada de hacer visible los servicios para que aplicaciones externas se puedan conectar (front, apps, etc).

Tutorial paso a paso

En el siguiente video explico paso a paso como crear un CRUD sencillo empleando una clase llamada Persona.

Modelo

La clase Persona tiene los atributos que deseamos guardar en la base de datos.

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table (name = "persona")
public class Persona {
	
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	private Long id;
	
	private String nombre;
	private String apellido;
	private String correo;
	
	
	
	
	public Persona () {
		
	}
	
	
	
	public Persona(Long id, String nombre, String apellido, String correo) {
		this.id = id;
		this.nombre = nombre;
		this.apellido = apellido;
		this.correo = correo;
	}
	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 String getApellido() {
		return apellido;
	}
	public void setApellido(String apellido) {
		this.apellido = apellido;
	}
	public String getCorreo() {
		return correo;
	}
	public void setCorreo(String correo) {
		this.correo = correo;
	}
	
}

Repositorio

Como podrás ver, esta interface no tiene ningún método, a no ser que quieras crear métodos personalizados.

import org.springframework.data.jpa.repository.JpaRepository;

public interface PersonaResporitory extends JpaRepository<Persona, Long>{

}

Servicio

La clase servicio usa el repositorio para tener todo de forma ordenada a la hora de llamarlo desde el rest.

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;



@Service
public class PersonaService {
	
	@Autowired
	private PersonaResporitory personaResporitory;
	
	
	public Persona create (Persona persona) {
		return personaResporitory.save(persona);
	}
	
	public List<Persona> getAllPersonas (){
		return personaResporitory.findAll();
	}
	
	public void delete (Persona persona) {
		personaResporitory.delete(persona);
	}
	
	public Optional<Persona> findById (Long id) {
		return personaResporitory.findById(id);
	}
	

}

Rest

import java.net.URI;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import xyz.yoandroide.tutorial.model.Persona;
import xyz.yoandroide.tutorial.service.PersonaService;

@RestController
@RequestMapping ("/api/persona/")
public class PersonaREST {
	
	@Autowired
	private PersonaService personaService;
	
	@PostMapping
	private ResponseEntity<Persona> guardar (@RequestBody Persona persona){
		Persona temporal = personaService.create(persona);
		
		try {
			return ResponseEntity.created(new URI("/api/persona"+temporal.getId())).body(temporal);
			
		}catch (Exception e) {
			return ResponseEntity.status(HttpStatus.BAD_REQUEST).build();
		}
	}
	
	
	@GetMapping
	private ResponseEntity<List<Persona>> listarTodasLasPersona (){
		return ResponseEntity.ok(personaService.getAllPersonas());
	}
	
	@DeleteMapping
	private ResponseEntity<Void> eliminarPersona (@RequestBody Persona persona){
		personaService.delete(persona);
		return ResponseEntity.ok().build();
	}
	
	@GetMapping (value = "{id}")
	private ResponseEntity<Optional<Persona>> listarPersonasPorID (@PathVariable ("id") Long id){
		return ResponseEntity.ok(personaService.findById(id));
	}
	

}

POM

Obviamente aquí solo te he dejado la propiedades y las dependencias del POM, aunque si lo creaste como lo hice en el tutorial del vídeo, no necesitaras agregar dependencias de forma manual, puestas estas se agregan automaticamente.

<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>

Archivo de configuración

Recuerda que la primera vez que corras el proyecto debes dejar descomentadas las ultimas 3 lineas, después tendrás que comentarlas para evitar que te borre la base de datos cada vez que inicies o corras nuevamente el proyecto.

spring.jpa.database=POSTGRESQL
spring.datasource.platform=postgres
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=
spring.jpa.show-sql=true
#spring.jpa.generate-ddl=true
#spring.jpa.hibernate.ddl-auto=create-drop
#spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true

Recomendado:   Consumir API de Deezer con Android Studio: Proyecto completo
Subir