En este artículo trabajaremos con Spring Boot y con Spring Data. Mediante a estos dos módulos de Spring, crearemos un CRUD REST SERVICE mediante a JPA y al motor de BBDD MySQL.
Dependencias para el proyecto
Las dependencias que utilizaremos en para el proyecto serán:
- Spring-boot-started-web: Iniciador para crear aplicaciones web, incluidas RESTful, que utilizan Spring MVC. Utiliza Tomcat como el contenedor integrado predeterminado.
- MySql-connector-java: JDBC Type 4 driver para el motor de BBDD MySQL.
- Spring-boot-started-data- jpa: Iniciador para usar Spring Data JPA con Hibernate.
- Spring-boot-starter-test: Iniciador para probar aplicaciones Spring Boot con bibliotecas que incluyen JUnit, Hamcrest y Mockito. Aunque no estrictamente necesario será el encargado de permitirnos realizar los test.
Creando la BBDD
Bien, vamos a crear una BBDD llamada DB_SHOP que tendrá una tabla llamada Customers en su interior.
Application.properties
Desde el application.properties configuraremos la BBDD, pasando le parámetros como la url, el username y la password.
¿Qué es JPA?
JPA son las iniciales de Java Persistence Api.
JPA, es el encargado de permitirnos «olvidarnos» de la capa de base de datos. Con olvidarnos, nos referimos a abstraernos de la capa de datos, es decir, olvidarnos de su funcionamiento y que sea JPA de Spring la que lo gestione por nosotros como se comunica la BBDD con la siguiente capa. Esta abstracción se conoce bajo el concepto de abstracción DAO o ORM.
DAO Data Access Object o ORM Object Relational Maping. Ambos conceptos son lo mismo.
Si miramos un par de esquema más detallados, podemos comprobar como se estructura la arquitectura de nuestra aplicación REST y las diferentes capas, como si de una «cebolla» se tratase que compondrán nuestra aplicación.
En esta primera imagen, únicamente hay que matizar que la BBDD será MySql.
Por tanto, JPA no es nada más y nada menos que un conjunto de clases y métodos cuya finalidad es satisfacer nuestras necesidades de persistencia, es decir, permitirnos comunicarnos con una BBDD con la finalidad de obtener.
Estructura del proyecto
La estructura de package será:
- com.restfull.core: contendrá el main de la aplicación.
- com.restfull.core.controllers: contendrá la definición de los controlladores que posteriormente, se implementarán en com.restfull.core.controllers.impl.
- com.restfull.core.controllers.impl: contendrá los controladores que nos permitiran realizar ends points para responder a nuestra petición.
- com.restfull.core.repository: será la capa sobre la que añadiremos JPA.
- com.restfull.core.entities: las entidades son la manera que tenemos de declarar los capos que tiene la tabla que queremos que mapeé JPA (no tienen porque ser todos).
- com.restfull.core.service: contendrá la definición de los servicios, que en este caso, posteriormente se implementaran en com.restfull.core.serviceImpl.
- com.restfull.core.serviceImpl: contendrá los servicios. Esta capa es la capa de negocio, la encargada de otorgarle cierta inteligencia al microservicio.
La buena práctica es que el repositorio pase por el servicio y posteriormente sea el controlador el que lo devuelva. Y por tanto, así lo haremos.
Creando la entidad (com.restfull.core.entities)
Bien, para crear el repositorio de JPA, primeramente necesitamos añadir la entidad que mapeará los datos de la tabla de SQL que le especifiquemos de SQL para posteriormente ir transformándolos en objetos.
Creando la capa de repositorio (JPA)
Bien, ahora vamos a crear la capa de repositorio mediante a JPA. Para ello, vamos a extender de JpaRepository, tenéis los imports arriba ante cualquier problema para poder revisarlos.
Y posteriormente, vamos a mapear la capa customer por tanto entre los <> añadimos primeramente la tabla a mapear y le indicamos que el PK sobre el que recorreremos la tabla será de tipo Long.
CustomerService
En CustomerService añadimos el listado de métodos que posteriormente implementarlos en serviceImpl. Esto, nos otorga el beneficio de poder implementar estos métodos en diferentes clases a modo de herencia.
CustomerServiceImpl
Bien, ahora creamos el CustomerServiceImpl que heredará el listado de métodos que acabamos de definir anteriormente en CustomerService. Estos métodos estarán vacíos y deberemos ir rellenandolos nosotros.
CustomerController
Y volvemos a repetir lo mismo que hemos hecho en el CustomerService pero en este caso para realizar los controladores del CustomerController, que posteriormente heredaremos mediante a su implementación en CustomerControllersImpl:
CustomerControllerImpl
Y finalmente creamos nuestro CustomerControllerImpl en el que llamaremos a la inteligencia que hemos depositado en la capa de servicio.
Testeando el CRUD
Cuando lanzamos peticiones a nuestro microservicio que acabamos de crear, vamos a ver que nos responde en formato JSON. Este tipo de formato puede ser un poco lioso de leer. Pero es bastante normal que sea así debido a que la finalidad es transmitir información, no el facilitar su lectura. De esto último, en principio, se debería de encargar la capa de presentación. Pero si pese a ello queremos facilitarnos su lectura, contamos con ningún pluggin para ello. Nosotros utilizaremos JSON View disponible para Google Chrome.
Test
El end point http://localhost:8888/test tiene como finalidad testear que el microservicio este levantado. Si hacemos unapetición al endpoint, con el microservicio arrancado, nos aparecerá un mensaje
FindAllCustomers
Vamos a mostrar todos los Customers mediante al endpoint http://localhost:8888/customers.
Anteriormente hemos dicho que había una diferencia avismal entre usar un pluggin o no usarlo. Un ejemplo sería:
FindCustomerById
Bien, hasta ahora hemos visto todos los Customers disponibles en nuestra BBDD. ¿Pero que pasa si solamente queremos buscar 1? ¿Tenemos que buscarlos entre todos los Customers disponibles? La respuesta a ambas preguntas es no y por ello hemos creado FindById, cuyo endpoint es:
AddCustomer
Si hacemos una petición vía POSTMAN de tipo POST a localhost:8888/customers/add y añadimos los siguientes campos:
Podemos ver que su respuesta es añadir a un nuevo Customer.
DeleteCustomer
Si queremos eliminar un Customer utilizamos el end point http://localhost:8888/customers/delete/3
Si el Customer existe, nos mostrará un mensaje de confirmación:
Y si no existe, nos mostrará un mensaje de aviso:
UpdateCustomer
Y por fin, el UpdateCustomer último end poind http://localhost:8888/customers/update
Si cargamos ahora Customer1, podemos ver como ahora si que hemos añadido los valores (aunque no todos).
Conclusión
Aunque es un ejercicio bastante denso, se puede mejorar en muchos aspectos. Sobretodo en el manejo de Excepciones aunque el objetivo de este tutorial era mostrar la estructura básica de un proyecto.
Os dejo un link del repositorio del proyecto de GitHub: https://github.com/DavidBernalGonzalez/CRUDinJPASpringBoot
Un saludo javer@s!