Si en nuestras aplicaciones tenemos peticiones que tardan mucho tiempo, varios segundos, pueden surgir problemas: peticiones que acaben en timeout, bloqueo de recursos en el backend, etc. Para solucionar esto y optimizar estas consultas, debemos hacerlas de forma asíncrona. Para ello, tendremos que hacer la petición desde nuestro frontend, recibir un id del backend, e ir haciendo pooling desde el front hasta que estén listos los datos. Los pasos serían los siguientes:
Veamos como implementaríamos esto en ambas partes.
Después de la primera petición, con la que obtendremos el id de solicitud, para hacer pooling podemos hacerlo de la siguiente manera:
obtenerResolucion(numSolicitud) {
// Llamada al método REST para obtener los datos
ServicioRest.obtenerResolucion(numSolicitud, this.token)
.then((response) => {
if(response.status === 202){
// Si no están listos los datos esperamos para volver a hacer la petición, en este caso 5000ms, 5s, le ponemos tiempo de espera que queramos
setTimeout(()=>{this.obtenerResolucion(numSolicitud)}, 5000);
} else {
// Procesamiento de los datos ya obtenidos
...
}
})
// Si se produce un error lo indicamos con un toast
.catch(() => {
this.$store.dispatch("global/setShowSpinner", false); // Quitamos el spinner de carga - Hay que adaptarlo a cómo lo hagamos en nuestra aplicacion
this.$toast.add({
severity: "error",
summary: "Error",
detail: "Se ha producido un error en el proceso.",
life: 3000,
});
});
}, |
Para ejecutar código de forma asíncrona en Spring Boot, podemos utilizar CompletableFuture.runAsync( ... ), y con esto el método que inicia la solicitud tendría esta estructura:
public ResponseEntity<String> solicitudDatos( ... ) {
// Inicia proceso y obtiene id
String id = iniciaProceso() //Función que cree el registro en base de datos y devuelva el id
CompletableFuture.runAsync( () -> {
// Código asíncrono, que termine poniendo el resultado en base de datos
});
// Devolvemos el id de la peticion
return ResponseEntity.ok(id);
} |
Y para el método al que el front estará haciendo pooling solo necesitaremos una consulta normal a base de datos, con un JpaRepository, y comprobar si el campo de los datos está vacío o no, dando la respuesta correspondiente.