Hola, muy buenas tardes a todos.
Debido al éxito del vídeo de la primera parte sobre la creación del modelo y de su configuración en el "application.properties"; ahora nos concentraremos en la parte de la constitución de su respectivo repositorio y servicio que son partes esenciales de una API Rest con Spring Boot y JPA, conectando a MySQL.
En todo caso, hoy voy a tratar sobre ¿Qué es un repositorio, y que es un servicio en un API Rest?
En resumidas cuentas, un repositorio visto desde un archivo en Java no es más que una interfaz que hereda de una serie de "Repositories" y una de ellas en la que vamos a trabajar en este vídeo (artículo) es la de JPA Repository, aunque también podríamos mencionar el CRUDRepository.
Para darle un significado más concreto, un repositorio es una lista de instrucciones por el cual está previamente configurado para que el administrador de sistema, y también, el usuario final, pueda ejecutar las operaciones determinadas, algunas como, buscar por ID, guardar la información en su respectiva bases de datos, o darle al usuario en sí, la facultad de eliminar un dato en la DB.
Generalmente un archivo como el JPARepository es un archivo .class en Java, lo que efectua realmente son las tareas que hace en el CRUD que estamos realizando, y por consiguiente, dichas tareas son agrupadas como métodos con y sin parámetros, la estructura del JPARepository viene a asemejarse a una interfaz, que no es más que, un conjunto de métodos o firmas que llevan o no parámentros.
La sintáxis de nuestro UserRepository, queda expreso de la siguiente forma, aunque también podemos incluir en dicho repositorio, los métodos o firmas definidos por el usuario:
@Repository
public interface UserRepository extends JpaRepository<UserModel,Long>
{
Como puede saber, el archivo UserRepository (repositorio), reune todos los métodos que HEREDAN de la clase JPARepository, llevando consigo dos parámetros encerrados en dos símbolos menor y mayor que, dichos parámetros son determinados como: 1. El tipo de Model (que aparece como UserModel), y 2. El tipo de dato al cuál está asociado la llave primaria ID del archivo UserModel que en este caso es Long.
Como regla general, todo archivo que esté relacionado con el repositorio, se emplea la anotación @Repository.
En resumen, un repositorio no es más que, una colección de métodos heredados de una clase en específico (en este segundo vídeo empleamos el JPARepository) que llevan dos parámetros dados, uno para el tipo de Modelo, y el otro para el tipo de dato que es la llave primaria perteneciente al Modelo perse.
Ahora pasemos de una vez a lo que es un Servicio en una APIRest con Spring Boot, podría deducir que, un servicio no es más que la inyección de los métodos dados en la interfaz UserRepository (más exactamente del repositorio de nuestra APIRest), salvo que, para que se pueda implementar nuestro Servicio a partir de lo anterior, se emplea la anotación @Autowired.
La anotación @Autowired es súper
importante utilizarla ya que es una de las partes más indispensables a la hora
de crear nuestra APIRest, palabras más, palabras menos; dicha anotación hace
las veces de una llave que nos permite "conectar", en este caso,
nuestro Repository con el servicio. En nuestro artículo (vídeo), se empleará
todo el conjunto de métodos que parte de nuestro repositorio, y como de ahorrar
código se trata, vamos a crear nuestro servicio por medio de las interfaces, no
obstante, y partiendo de lo anterior, esta porción de código es por el cuál nos
permite "inyectar" nuestro repositorio, al servicio:
@Autowired
UserRepository userRepository;
Todo archivo que esté asociado a un Servicio en SpringBoot, es indispensable el uso de la anotación @Service, para indicar que dicho elemento es un servicio como tal. Antes de proceder con la implementación del repositorio y del servicio en sí, para nuestra API Rest, se debe crear los siguientes paquetes, uno para el Repositorio y otro para el servicio:
![]() |
Fig 1. - Procedimiento para agregar un paquete en Java (ampliar imágen - Parte 1) |
Sólamente haciendo clic derecho del ratón en dónde está el paquete principal de nuestro proyecto, luego le damos en New ->Package, para luego desplegar un cuadro en dónde seleccionaremos Interface bajo los nombres de UserRepository y UserServiceInterface (este último nos ayuda cuándo vayamos a implementar los métodos de la interfaz UserServiceInterface, nos ayuda un montón a la hora de escribir código), Un submenú nos aparecerá después de haber realizado el procedimiento previo:
![]() |
Fig 2. - Submenú para definir al usuario qué se va a crear |
La apariencia en la barra del explorador quedará así:
![]() |
Fig 3. - Vista de la barra del explorador de IntelliJIDEA (Nótese que están las interfaces para el repositorio y el servicio) |
Después de los pasos anteriormente descritos, vayamos al archivo UserRepository que está en el paquete del mismo nombre, y vamos a heredar todos los atributos de la clase JPARepository, además de implementar nuestras propias firmas (o clases en sí, porqué una interfaz es una plantilla para definir unas clases por el cuál el usuario debe definir que se va a hacer con ellas), antes de iniciar con la escritura o bien, la implementación en código, se debe colocar la anotación @Repository, encima de "public interface" para definir de que en sí, es un repositorio:
package com.toadsdewin.basicCrud.UserRepository;
import com.toadsdewin.basicCrud.UserModel.UserModel;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserRepository extends JpaRepository<UserModel,Long>
{
public List<UserModel> findByCountry(String country);
public List<UserModel> findByOccupation(String occupation);
public List<UserModel> findByProfession(String profession);
public List<UserModel> findByAge (Integer age);
}
Nuestro repositorio contiene todos los métodos heredados de la clase JPARepository, más otros tres que son definidos por nosotros como son:
- findByCountry: lleva por parámetro un objeto de tipo String cuya palabra es country, nos indica el país por el que debemos buscar.
- findByOccupation: el mismo significado que findByCountry, sólo que éste nos permite indexar la ocupación otorgada a la persona que se agregó en nuestra DB.
- findByProfession: la misma función que findByCountry, sólo que ésta nos permite indexar la profesión de la persona que está en nuestra DB.
- findByAge: lleva por parámetro un objeto de tipo Integer cuya palabra es age, nos indica que podemos buscar un listado de usuarios que tenga una determinada edad.
package com.toadsdewin.basicCrud.UserService;
import com.toadsdewin.basicCrud.UserModel.UserModel;
import java.util.List;
public interface UserServiceInterface
{
public boolean deleteUser(Long id);
public List<UserModel> getUsers();
public List<UserModel> getByCountry(String country);
public List<UserModel> getByOccupation(String occupation);
public List<UserModel> getByProfession(String profession);
public List<UserModel> getByAge(Integer age);
public UserModel saveUser(UserModel user);
public UserModel upgradeUser(UserModel user,Long id);
public UserModel getById(Long id);
}
En esta interfaz de UserServiceInterface (valga la redundancia), tenemos nueve métodos compuestos de cuatro elementos de tipo List (de java.util.*), tres del tipo UserModel (viene del modelo), y un primitivo de tipo lógico o boolean. Al implementar nuestra interfaz, previa creación del código UserService y también de la implementación de nuestras anotaciones @Service y @Autowired, nos quedará de la siguiente forma, eso sí siguiendo los pasos dados a partir de la Figura 1:
package com.toadsdewin.basicCrud.UserService;
import com.toadsdewin.basicCrud.UserModel.UserModel;
import com.toadsdewin.basicCrud.UserRepository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Objects;
@Service
public class UserService implements UserServiceInterface
{
@Autowired
UserRepository userRepository;
@Override
public boolean deleteUser(Long id) {
try {
userRepository.deleteById(id);
return true;
}
catch (Exception error)
{
error.getMessage();
}
return false;
}
@Override
public List<UserModel> getUsers() {
return (List<UserModel>)userRepository.findAll();
}
@Override
public List<UserModel> getByCountry(String country) {
return userRepository.findByCountry(country);
}
@Override
public List<UserModel> getByOccupation(String occupation) {
return userRepository.findByOccupation(occupation);
}
@Override
public List<UserModel>getByProfession(String profession)
{
return userRepository.findByProfession(profession);
}
@Override
public List<UserModel> getByAge(Integer age) {
return userRepository.findByAge(age);
}
@Override
public UserModel saveUser(UserModel user) {
return userRepository.save(user);
}
@Override
public UserModel upgradeUser(UserModel user, Long id) {
try {
UserModel upgrade = userRepository.findById(id).get();
if (Objects.nonNull(user.getName()) && !"".equalsIgnoreCase(user.getName()))
{
upgrade.setName(user.getName());
}
if (Objects.nonNull(user.getSurname()) && !"".equalsIgnoreCase(user.getSurname()))
{
upgrade.setSurname(user.getSurname());
}
if (Objects.nonNull(user.getCountry()) && !"".equalsIgnoreCase(user.getCountry()))
{
upgrade.setCountry(user.getCountry());
}
if(Objects.nonNull(user.getOccupation()) && !"".equalsIgnoreCase(user.getOccupation()))
{
upgrade.setOccupation(user.getOccupation());
}
if(Objects.nonNull(user.getProfession())&& !"".equalsIgnoreCase(user.getProfession()))
{
upgrade.setProfession(user.getProfession());
}
if(Objects.nonNull((user.getAge()))&&! "".equals(user.getAge()))
{
upgrade.setAge(user.getAge());
}
return userRepository.save(upgrade);
}catch(Exception error)
{
error.getMessage();
}
return null;
}
@Override
public UserModel getById(Long id) {
return userRepository.findById(id).orElse(null);
}
}
Hasta el momento, esta es la parte de la implementación de nuestro repositorio y servicio, respectivamente; para que se vea realmente la ejecución de nuestros dos elementos, nos hace falta un elemento bien indispensable, se podría decir que es el santo grial del desarrollo de una API Rest con Spring Boot, y no es más que su @Controller, o controlador en sí, para esta última parte de nuestra implementación, les explicaré no solamente qué es y como funciona un controlador, sino que también voy a tocar el tema de los estados HTTP que aparecen en sus respectivas anotaciones aparte del @Controller. Eso sí, nos vemos en el siguiente post (vídeo).
No hay comentarios.:
Publicar un comentario