CRUD/REST con Spring Boot (+ Video)

El patrón de caso de uso CRUD es de los más populares y usados en nuestras aplicaciones, en este artículo veremos como crear un CRUD básico sobre una entidad usando las bondades de Spring Boot. Este artículo es dirigido sobre todo a programadores que están iniciando en el mundo Java/Spring Boot / REST APIs. Al final dispone de un vídeo en nuestro canal de Youtube que tiene toda la explicación.

Arquitectura del ejemplo

El ejemplo que mostraremos a continuación tiene una estructura en capas, que son reflejadas a los paquetes de la aplicación.

  • entities: Expone la entidad Auto (incluye elementos de persistencia)
  • repository: Acceso al repositorio (persistencia, heredado de Spring data JPA).
  • service: Lógica principal.
  • web: Controlador REST.

Dependencias

El proyecto se basa en Spring Boot, las dependencias principales son:

  • Spring Boot Starter Parent: Base de Spring Boot.
  • Spring Boot Starter Web: MVC
  • Spring Boot Starter JPA: Acceso a datos.
  • Driver de MySQL.
  • Lombok

Código o por capas

Entidad Auto, representa la entidad y el modelo de datos de la aplicación.

import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.Id;
@Data
@Entity
public class Auto {
    @Id
    private Long id;
    private String marca;
    private int anno;
    private int capacidad;
    private double precio;
}

AutoRepository: Usa Spring Data JPA para rápido acceso a las operaciones CRUD.

import org.springframework.data.repository.CrudRepository;
public interface AutoRepository extends CrudRepository<Auto, Long> {
}

IAutoService: Se define una interfaz con las operaciones y luego se implementa.

import java.util.Optional;
public interface IAutoService {
     Auto crear(Auto auto);
     Optional<Auto> obtenerPorId(Long id);
     Auto actualizar(Long id, double nuevoPrecio);
     boolean eliminar(Long id);
}
@Service
public class IAutoServiceImpl implements IAutoService {
    @Autowired
    private AutoRepository autoRepository;
    @Override
    public Auto crear(Auto auto) {
        return this.autoRepository.save(auto);
    }
    @Override
    public Optional<Auto> obtenerPorId(Long id) {
        return this.autoRepository.findById(id);
    }
    @Override
    public Auto actualizar(Long id, double nuevoPrecio) {
        Optional<Auto> auto = this.autoRepository.findById(id);
        if (auto.isPresent()) {
           Auto tmp = auto.get();
           tmp.setPrecio(nuevoPrecio);
           return crear(tmp);
        }
        return null;
    }
    @Override
    public boolean eliminar(Long id) {
        this.autoRepository.deleteById(id);
        return true;
    }
}

AutoResource: Controlador REST, provee acceso a las operaciones del CRUD por HTTP REST.

@RestController
@RequestMapping("/api/v1")
public class AutoResource {
    @Autowired
    private IAutoService autoService;
    @PostMapping("autos")
    public ResponseEntity<Auto> crearAuto(@RequestBody Auto auto) {
        return new ResponseEntity(this.autoService.crear(auto), HttpStatus.CREATED);
    }
    @GetMapping("/autos/{id}")
    public ResponseEntity<Auto> obtenerAuto(@PathVariable("id") Long id) {
        Optional<Auto> optionalAuto = this.autoService.obtenerPorId(id);
        if (optionalAuto.isPresent())
            return new ResponseEntity(optionalAuto.get(), HttpStatus.OK);
        return ResponseEntity.notFound().build();
    }
    @PutMapping("/autos/{id}/nuevoprecio/{precio}")
    public ResponseEntity<Auto> actualizarAuto(@PathVariable("id") Long id, @PathVariable("precio") double precio) {
        Auto autoActualizado = this.autoService.actualizar(id, precio);
        if (autoActualizado != null) {
            return new ResponseEntity(autoActualizado, HttpStatus.OK);
        }
        return ResponseEntity.notFound().build();
    }
    @DeleteMapping("/autos/{id}")
    public ResponseEntity<Void> eliminarAuto(@PathVariable("id") Long id) {
        this.autoService.eliminar(id);
        return ResponseEntity.noContent().build();
    }
}

Además las configuraciones del proyecto fueron escritas en application.yml, específicamente las relacionadas con la conexión a bases de datos.

server:
  port: 8100
spring:
  application:
    name: auto
  datasource:
    url: jdbc:mysql://localhost:3306/auto
    username: root
    password: root
    platform: mysql
  jpa:
    hibernate:
      ddl-auto: update

Espero te sea útil el artículo, si deseas ver una explicación ampliada de este artículo puedes ver en el canal de Youtube.

El código del ejemplo está accesible en el repositorio de GitHub.