race-801940_640Cuando estamos haciendo un diseño SOA, es de lo más común que surja la necesidad de realizar servicios compuestos (más nos vale que sea así). Sin embargo, dentro de este tipo de servicios, hay uno que tarde o temprano nos veremos obligados a abordar, el de componer servicios en paralelo.

El problema

Me refiero a la situación en que tenemos fuentes de información, de varios backends de distinta naturaleza, con unos tiempos de respuesta dispares, pero que queremos presentar al cliente de una manera conjunta, agregada.

El caso más simple es el de una posición integral en una web bancaria. Cuando se quiere presentar los datos al usuario en una pantalla donde se muestra por ejemplo los saldos de sus cuentas corrientes, el gasto en cada una de sus tarjetas, la situación de sus préstamos su plan de pensiones, etc. etc.

Por simplificar digamos que nuestra posición integral se forma a partir de la información suministrada por ocho backends diferentes y que cada uno de ellos nos ofrece un servicio web.

Por supuesto, nunca es tan simple como esto ya que lo normal es que al menos varios de estos backends no proporcionen servicios web. Si no es así, tendremos que lidiar con tecnologías diferentes, legacy en algunos casos y en otros, aún peor, con tecnologías propietarias.

Si pensamos en este escenario, lo lógico sería implementar antes los servicios web necesarios para exponer de una manera estándar la funcionalidad de los backends que aún no lo hacen. Claro que el que tendría que implementar estos servicios sería el dueño de la lógica de backend, no nosotros que seríamos en este caso sus consumidores. Sin embargo, no nos deberá sorprender que nos tocase implementar unos cuantos servicios (SOAP o REST). No hay mayor acicate que la necesidad para que algo se haga.

¿Un servicio compuesto?

Ahora bien, para la posición integral, lo normal sería hacer un servicio compuesto que reutilice los servicios atómicos, de backend, e integre la información que recuperamos de cada uno de ellos.

Aquí puede que venga el primer problema ya que seguramente cada uno de los backends no utilice servicios canónicos, o lo que es lo mismo, que o utilicen el mismo lenguaje o definición de datos. Por lo tanto, tendremos que hacer una transformación de datos que puede ser mayor o menor en función del número de datos que haya que transformar y lo mucho o poco que se parezcan entre sí.

Dependiendo de la tecnología utilizada esto puede ser un verdadero problema de rendimiento. No sería la primera vez en que las transformaciones y no la lógica de negocio, arruinan el tiempo de respuesta de un servicio. Y es que en los ESB se utiliza a menudo el XSLT para transformar mensajes y si el conjunto de datos es grande, la ejecución de estas hojas de transformación pueden ser desesperadamente lentas.

El entorno móvil

No desvelo nada nuevo si digo que el entorno móvil, y también en las webs SPA (single page architecture), nos hacen cambiar un poco el concepto de lo que dábamos por supuesto en otro tipo de aplicaciones.

Como decía anteriormente, en el caso de un servicio de posición global, lo lógico sería hacer un servicio que haga una llamada a los backends. Esta llamada se tendría que hacer en paralelo (de manera concurrente) a ser posible, y convertir los datos que sean necesarios y luego juntarlos todos para dar una única respuesta al cliente del servicio. Evidentemente este servicio compuesto será tan lento como el más lento de los servicios de backend a los que llama.

Más problemas…

¿Que pasa entonces con el usuario que está mirando la pantalla de su móvil esperando por sus datos? Que por muchos adornos que pagamos en la pantalla con relojillos girando, tendrá que esperar unos cuantos segundos, puede que decenas de segundos, hasta que el servicio compuesto pueda responder (siempre suele haber un backend que se atasca o que timeout).

¿Que hacemos entonces para mejorar la percepción del usuario?. Lo que se suele hacer entonces es ir pintando cada trozo de pantalla con la información correspondiente según se vaya recibiendo.

Si un backend es más rápido en responder , o si la información es consultada más a menudo y ya está cacheada, el usuario ya podrá estudiar la informa mientras que la restante va llegando. Así pues, ¿no deberíamos hacer el servicio compuesto? Parece un contrasentido… pero lo cierto que en este caso es mejor no hacerlo y dejar que las ocho invocaciones a los backens se hagan de manera independiente.

Conclusión

Así pues, no siempre lo que parece la solución más intuitiva es la que finalmente debemos llevar a cabo. Por desgracia, no podemos aislarnos totalmente de las circunstancias en las que se consume nuestro servicio.