sábado, 14 de julio de 2018

Finch vs Akka Http: Hola mundo en Scala


Hace varios días, buscando artículos sobre Scala en Medium, encontré un artículo sobre cómo crear una aplicación de lista de tareas utilizando Finch, que me llamó la atención. Este tenía un enlace a un artículo titutlado ¿Qué tan rápido es Finch?. En este artículo se mostraba el siguiente tweet con una gráfica comparativa de la velocidad de distintas librerías HTTP de Scala:



Siendo fanático de Scala, y estando acostumbrado a las herramientas más divulgadas para servicios web tales como Play Framework, Spray y Akka HTTP, me llamó bastante la atención que Finch mostrara por mucho un mejor desempeño que estas herramientas, a pesar de que la publicación tiene más de 2 años (publicada en febrero de 2016, vista por mí a principios de 2018). Así que me dio curiosidad de ver qué era Finch, hacer una pequeña prueba, y comparar el código con una aplicación similar con Akka HTTP.

¡Hola Finch!

Finch es una API de Scala para construir servicios HTTP sobre Finagle, la cual es un "sistema RPC extensible para la JVM, utilizado para la construcción de servidores de alta concurrencia", utilizando APIs uniformes de cliente y servidor agnósticas del protocolo (creo q podría describir a Finagle como el WCF para la JVM). En este sentido, Finch provee una delgada capa de bloques para construir APIs HTTP de forma tipada, utilizando conceptos de programación funcional. Esto convierte a Finch en una excelente herramienta para la creación de microservicios, ya que es más fácil integrarlos utilizando tipos compartidos. Cabe mencionar además que Finagle corre sobre Netty, por lo que no requiere de un servidor web separado.

Debido a que Scala es para mí más un pasatiempo, ya que no lo uso en mi trabajo, me costó un poco entender cómo se definía una API en Finch. Después de batallar un par de horas, pude crear el siguiente Hola Mundo, en un solo archivo:



Nótese que la API se compone de un solo endpoint, el cual es pasado como parámetro al servidor HTTP, para ser servido (valga la redundancia). Luego el programa queda en espera mientras el servicio se mantiene en ejecución. Las rutas se definen para cada endpoint, y los separadores utilizados en código son un par de dos puntos (::). Por otra parte, para la serialización de los datos desde y hacia JSON se usa Circe (antes llamada "JSON para gatos", vaya usted a saber por qué, jejeje).

El código completo pueden encontarlo acá: https://github.com/guillegr123/its-hellofinch

El proyecto se ejecuta utilizando SBT, con el siguiente comando:
sbt run
Luego, para probar el servicio, abrimos en el navegador la ruta: http://localhost:8080/api/v1/hello

Lo que más me gustó de Finch es que es que la creación de servicios web requiere poco código, y permite crear una API tipada desde el principio, pudiéndose definir los modelos de datos utilizados en el request y el response. Además, los endpoints son asíncronos, lo que permite una mayor concurrencia, razón de su excelente desempeño.

Pero... luego de algunas pruebas, y de investigar un poco, descubrí que Finch no hace uso de las clases estándares de Scala para programación asíncrona, sino que usa las implementaciones propias del ambiente de Twitter, por lo que obligatoriamente tendremos que hacer uso de sus librerías. Esto además, aunque no imposibilita, hace un poco más engorroso integrar librerías que hacen uso de las clases estándar de Scala. En este sentido, me parece mejor utilizar Finch para aplicaciones pequeñas, o aplicaciones de microservicios en las que hagamos uso extensivo de Finagle y las librerías de Twitter.

¡Hola Akka HTTP!

Descubiertos estos detalles de Finch, y habiendo saciado mi curiosidad de probar el framework, decidí volver a mis raíces con Akka HTTP. Akka HTTP es el reemplazo de Spray, y es considerada más como una librería en lugar de un framework, ya que su principal objetivo es solo proveer herramientas para cubrir las necesidades de integración de una o varias aplicaciones vía HTTP, en lugar de lineamientos sobre los cuáles construir la aplicación. Como tal no provee manejo de componentes como CSS/Javascript, plantillas para creación de vistas y otras herramientas orientadas a aplicaciones para navegadores web.

La construcción del hola mundo utilizando Akka HTTP me costó menos que Finch, debido a que ya había hecho una prueba hace mucho tiempo (y el código fuente estaba en control de versiones). El servicio se creó en un solo archivo, al igual que el ejemplo anterior:



El código completo puede encontrarse acá: https://github.com/guillegr123/its-helloakkahttp

Al igual que con el proyecto de Finch, para ejecutar el servicio, basta ejecutar el comando:

sbt run

Y para probar el servicio, abrimos en el navegador la ruta: http://localhost:8080/api/v1/hello
 
A simple vista, el código es más grande. Esto se debe a que Akka HTTP usa los actores de Akka para el manejo de concurrencia, por lo que es necesario crear un sistema de actores, un materializador de actores, y obtener el contexto de ejecución. Además, para la serialización de los mensajes a JSON, es necesario definir un trait para el formateo del mensaje.

Aparte de eso, en esencia la definición de los endpoints es similar. Las rutas se establecen para cada enpoint, pero usando la barra diagonal (o pleca) como separador, lo que resulta un poco más natural que los dos puntos de Finch, pero que sirven al mismo propósito. Los enpoints son asíncronos, pero a diferencia de Finch, usa la implementación de Futures estándar de Scala.

De forma similar a Finch, la instancia de rutas de la API es pasada como parámetro a su propio servidor web, el cual es iniciado. Sin embargo, en este caso no utiliza una librería externa como Netty, sino que se ejecuta sobre los actores y los flujos de Akka, y activa un puerto para hacer uso directo del protocolo HTTP.

Por otra parte, a diferencia de Finch, al finalizar el servicio web, es necesario desconectar el servidor web explícitamente del puerto, y finalizar el sistema de actores.

Conclusiones

Luego de estas pequeñas pruebas, considero que ambas librerías son excelentes, pero poseen enfoques diferentes, así como implementaciones, por lo que pueden usarse de distintas formas. Akka HTTP parece ser la mejor opción cuando tenemos una aplicación creada utilizando las librerías estándar de Scala, o bien actores de Akka, y solo necesitamos integrar sus componentes u otras aplicaciones vía HTTP. Y Finch parece ser una buena elección cuando necesitamos crear interfaces web tipadas, o sistemas de microservicios que deseamos integrar de forma fácil, ya que también facilita la creación de clientes.

En cuanto al desempeño, según el workbench mostrado por Vladimir Kostyukov, Finch es mucho más rápido que Akka HTTP. Sin embargo, la comparativa fue realizada hace dos años, cuando Akka HTTP aún estaba en pañales, por lo que quedamos a la espera de una comparación más reciente. En lo personal espero más Akka HTTP por ser considerado el reemplazo de Spray.

Related Articles

0 comentarios:

Publicar un comentario

Con la tecnología de Blogger.