Backend de Comparabien.com.pe con JakartaEE, DeltaSpike y Blaze Persistence

 


Pre requisitos


En este artículo vamos a recordar 2 artículos previos que son:


Código Fuente


El código fuente del backend está en https://github.com/joedayz/ConcentradorJakartaEE.
El código fuente del frontend está en https://github.com/joedayz/concentrador.

La intención es revelar el gran trabajo de mi colega Jorge Pingo.

Jakarta EE y MicroProfile


En este artículo no usaremos Spring Boot, vamos a usar JakartaEE y Microprofile para poder usar las APIs que nos permitan crear servicios Rest con JAX-RS y persistencia con JPA, CDI. 



Apis de Jakarta EE





Apis de Microprofile




Persistence.xml

En este archivo configuramos el recurso JDBC que tendremos en Payara Server.



 En Payara Server estará definido el JDBC Connection Pool:




Y JDBC Resources:



Blaze Persistence


Para el Backend vamos a usar esta API que te permite escribir JPA Criteria queries que usa características avanzadas de SQL.  El código fuente del proyecto está en GitHub y ahí puede encontrar varios casos de uso.




DeltaSpike


Otro proyecto a utilizar en este proyecto es DeltaSpike que consiste de un número de extensiones portables CDI que proveen características útiles para los desarrolladores de aplicaciones Java. 
Esta requiere una implementación CDI que este disponible en runtime.
Estas características son adicionales a las provistas por la especificación CDI. En este link puedes encontrar la lista completa:


En el archivo apache-deltaspike.properties configuraremos:

globalAlternatives.org.apache.deltaspike.jpa.spi.transaction.TransactionStrategy = org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy
 

NOTA: 

Por defaecto el tipo de transacción usado por @Transactional es RESOURCE_LOCAL. Si tu configuras el tipo de  transaction-type="JTA" en el persistence.xml, tu tienes que habilitar otra TransactionStrategy en el beans.xml el cual es llamado org.apache.deltaspike.jpa.impl.transaction.BeanManagedUserTransactionStrategy.






Context Root


El context root se define en el archivo glassfish-web.xml de esta manera:




Modelo

En el paquete model encontrará las entidades JPA y las entidades relacionadas a vistas.




Repository

Gracias a DeltaSpike podemos tener un Repository que implementará por nosotros los métodos para persistir nuestra entidad y ademas podemos crear nuestro propio Query de objetos.





Muy parecido a Spring Data. 



Service

La capa de negocio podrá usar la capa repository sólo usando @Inject.




En esta capa encontraremos la clase ConsultaProductoServiceImpl.java   que usará el Criteria API para armar la consulta según los filtros que tenemos en la aplicación. Ademas de eso, paginado.  


Para lograr esto se usa DeltaSpike:

import com.blazebit.persistence.deltaspike.data.Page;
import com.blazebit.persistence.deltaspike.data.PageRequest;
import com.blazebit.persistence.deltaspike.data.Pageable;
import com.blazebit.persistence.deltaspike.data.Sort;
import com.blazebit.persistence.deltaspike.data.Specification;


Controller

Finalmente en esta capa tendremos los REST endpoints. Empezamos configurando la clase que hereda de Application. 


Y luego puedes crear tus clases controladoras para manejar los endpoints que necesites:


Como se puede ver, se puede definir el scope, el path principal y el formato de intercambio (JSON) entre servidor y clientes:   

@RequestScoped
@Path("/entidad-financiera")
@Produces("application/json")
@Consumes("application/json")
public class EntidadFinancieraController 


Ejecutando el Backend

Para probar la aplicación, primero asegurese de iniciar su payara server.


Luego configure en su IDE el payara server para poder desplegar la aplicación ahí:




Al ejecutar la aplicación Ud. verá el siguiente resultado:


Y podrá probar este endpoint (http://localhost:8080/api/v1/concentrador/opcion) para ver las opciones disponibles:




Configurando el Backend en  el FrontEnd

Para poder usar el backend, colocamos el endpoint base en el archivo environment.



BASE_ENDPOINT: 'http://localhost:8080/api/v1/concentrador'

Al ejecutar la aplicación obtendremos el siguiente resultado:





Y como se aprecia se puede ver las opciones disponibles que nos devuelve el backend.

Esperamos que lo disfruten.

Enjoy!

Joe



Share:

Comparabien.com.pe con Angular y NetCore - Parte 3




En la primera parte vimos cómo crear la estructura inicial de los proyectos FrontEnd y BackEnd de comparabien.com.pe, en la segunda parte vimos más a detalle la arquitectura de cada proyecto. En esta tercera parte veremos como trabajan los formularios reactivos en Angular implementados por nuestro amigo Jorge Pingo.


Código Fuente

El código fuente de este artículo lo encontrarán en https://github.com/joedayz/concentrador


Formularios Reactivos en Angular

Los formularios reactivos proporcionan un enfoque basado en modelos para manejar las entradas cuyos valores cambian todo el tiempo. 

En nuestro proyecto veremos como crear y actualizar un formulario básico tal cual lo hace la página comparabien.com.pe.

Importando Reactive Forms Module


Para trabajar con formularios reactivos hay que importar el módulo ReactiveFormsModule:



Depósito a Plazos


El ejemplo que vamos a analizar corresponde a Depósito a Plazos que según el routing es este Componente Web en Angular:




El formulario a manejar es el siguiente, el cual nos permitirá saber que tipo de depósito a plazo queremos: Moneda, Monto, Tiempo y Ubicación.



Formulario 1.0



El FiltroDepositoComponent es la clase TypeScript localizada en el archivo filtro-deposito.component.ts, el cual usará dos componentes, uno para el filtro previo y otro para mostrar los resultados del filtro preliminar. Esto lo podemos apreciar en el HTML:



El filtro-deposito.component.html está conformado de la siguiente manera:





Cómo se aprecia está el componente del filtro (app-compara-deposito) y la segunda parte sería el resultado de aplicar el filtro, que incluye también un filtro similar. Es decir, si en el FORMULARIO 1.0 damos clic al botón Comparar, pasamos a la siguiente ventana:




FORMULARIO 2.0


El que se muestre o no el FORMULARIO 1.0 o FORMULARIO 2.0 dependerá de la siguiente variable boolean llamado estado



<app-compara-deposito *ngIf="!estado" (emisor) = "cargarData($event)" (ocultar)= "ocultar($event)"></app-compara-deposito>

 Pero, también usaremos el siguiente truco para mostrar solo el div si estamos en el componente resultado (FORMULARIO 2.0) y no mostrar el pre filtro (FORMULARIO 1.0).



<div *ngIf="route.children.length != 0">
  Some content that should only be shown when the user is at the child component itself.
</div>

<router-outlet></router-outlet>


 

ComparaDepositoComponent

El primer componente corresponde al FORMULARIO 1.0. 




Usaremos una variable form de tipo FormGroup y fb de tipo FormBuilder para crear el formulario.

Si observamos el método ngOnInit revela la creación del formulario, la carga inicial del formulario y la carga de departamentos.


La carga de departamentos usa el departamentoService para traer la data desde nuestro backend. 



Si observamos el compara-deposito.component.html este va acorde al formulario creado en el componente, como puedes observar en <form [formGroup]="form"> :





Los componentes utilizados los puedes encontrar en https://www.primefaces.org/primeng/showcase/#/, si observas se ha usado <p-card>, <p-slider>, <p-dropdown>.

Al hacer clic en "Comparar" se llama al método filtrar().








Este método emite el valor del objeto filtro de tipo ConsultaFiltro, el cual guarda  lo que hayamos guardado en el formulario cómo: CODIGO_DEPOSITO, tipoMoneda, valorDeposito, plazo, departamento y banco.




También se emite la opción de ocultar para que pasemos al FORMULARIO 2.0 en la vista padre.



FiltroDepositoComponent

El formulario padre es este y de la misma manera tenemos variables para controlar el formulario.



En el formulario se crea el formulario y se carga con los valores seleccionados en el anterior formulario.



Como se ve ahí se comprueba si el filtro del primer formulario es diferente a null para establecer los valores previamente seleccionados.

La carga de departamentos es similar a lo visto en el primer formulario.

El listado de productos para los filtros seleccionados se da con el método listar() ubicado en el ngOnInit():




El filtro-deposito.component.html  muestra el formulario padre, el cual será precargado con los valores del formulario previo:






Este formulario es especial, porque si cambias el algún valor tiene que volverse a mostrar los productos acorde a dichos filtros. Por eso, vamos a observar la llamada al método filtrar() y en el caso del slider se usará en el onChange() el método activateAnimation().





El método se encarga de volver a listar los productos:


    this.servicioProducto.listar(filtro).subscribe(data => {
      this.servicioProducto.listaCambios.next(data);
    });

Este truco que vemos hace uso de un Subject:



De esta manera todos los que están suscritos a dicho Subject recibirán la nueva data y esta se mostrará actualizada donde se utiliza, dándonos una experiencia "reactiva".


Y esto se apreciará en la tabla de productos:





Cómo se aprecia, si ya te interesa un producto puedes ir al detalle:


              <button pButton type="button" pTooltip="Ver detalle" tooltipPosition="top" icon="fa fa-info"
                      class="p-button-raised p-button-success p-button-rounded p-button-sm boton_detalle"
                      [routerLink]="['detalle-deposito', datos.consultaEntidadProductoId]"></button> &nbsp;
              <button pButton type="button" pTooltip="Solicitar" tooltipPosition="top" icon="fa fa-arrow-circle-right"
                      class="p-button-raised p-button-warning p-button-rounded p-button-sm boton_detalle"
                      routerLink="/deposito/solicitud"></button>

Y esto es gobernado en el routing:



Gran trabajo de mi amigo Jorge Pingo implementando toda esta funcionalidad, espero, les haya gustado y lo puedan aplicar en sus proyectos.



Enjoy!

Jose



Share: