Header Ads Widget

Ticker

6/recent/ticker-posts

Uso de Spark para crear API en Scala

 

Uso de Spark para crear API: Scala-01

En nuestro artículo anterior, discutimos las fortalezas del lenguaje Java dentro del marco de Spark , destacando las formas en que Java Spark aumenta la simplicidad, fomenta el buen diseño y permite la facilidad de desarrollo.

En este artículo continuamos con nuestra cobertura sobre Spark , un micro framework ideal para definir y enviar rutas a funciones que manejan solicitudes realizadas a los puntos finales de su API web. Examinaremos el contrapunto de Java Spark, Scala Spark . Analizaremos el origen, las metodologías y las aplicaciones de Scala, así como algunos casos de uso en los que Scala Spark es muy eficaz .

Reintroduciendo Spark

En la primera parte de esta serie, Uso de Spark para crear API en Java , hablamos de Spark como un conjunto de herramientas para definir y enviar principalmente rutas a funciones que manejan las solicitudes realizadas al punto final de la API. Spark fue diseñado específicamente para hacer que estas definiciones de ruta sean rápidas y fáciles, utilizando las lambdas integradas en Java 8.

Cuando presentamos Spark por primera vez, usamos este ejemplo típico de Hello Word:

import static spark.Spark.*;

public class HelloWorld {
	public static void main(String[] args) {
    	get("/hello", (request, response) -> "Hello World");
	}
}

Cuando se ejecuta este fragmento, Spark activará un servidor web que servirá a nuestra API. Luego, el usuario puede navegar a http: // localhost: 4567 / hello, que llamará al lamba mapeado con el método spark.Spark.get. Esto devolverá Hello World.http : // localhost 4567 hello , que llamará al lamba mapeado con el método spark.Spark.get. Esto devolverá Hello World.

Consulte nuestra introducción de Spark para obtener más información sobre el historial de Spark, las capacidades de enrutamiento, incluidos los comodines en las rutas, el procesamiento de solicitudes / respuestas y la creación de plantillas.

Scala: su origen y propósito

La arquitectura básica y el diseño de Scala fue lanzado en 2001 en la Universidad de investigación École Polytechnique Fédérale de Lausanne (EPFL) por el científico informático alemán y profesor de métodos de programación Martin Odersky . Diseñado principalmente como un lenguaje compatible con el código de bytes de Java destinado a funcionar sin las deficiencias de Java propiamente dicho, Scala fue nombrado como un acrónimo de las palabras "escalable" y "lenguaje".

Este nombre destaca el objetivo de Scala propiamente dicho: un lenguaje extensible, potente y diseñado para crecer a medida que crecen las demandas de sus usuarios y desarrolladores. Debido a que el lenguaje se deriva del código de bytes de Java, es funcionalmente orientado a objetos por naturaleza.

Beneficios de Scala

Hay muchos beneficios inherentes a Scala que lo convierten en una excelente opción para una amplia gama de aplicaciones.

  • Funcional y útil : anteriormente hemos discutido la diferencia entre funcionalidad y usabilidad , y Scala cumple con estos dos requisitos muy diferentes con delicadeza. Scala está diseñado para admitir migración, sintaxis simple, inmutabilidad y compatibilidad cruzada con muchos otros lenguajes y extensiones .

  • Scalable by Design : Scala es la abreviatura de "Scalable", y se nota. Debido a que Scala es, por diseño, conciso en sintaxis y utiliza menos recursos que otros lenguajes, es experto tanto en aplicaciones pequeñas y portátiles como en sistemas grandes y complejos.

  • Orientado a objetos : Scala está completamente orientado a objetos por su propia naturaleza. Cada valor es un objeto y cada operación una llamada a un método; todo aumentado por clases y características complejas que permiten diseños y arquitectura avanzada. A diferencia de otros lenguajes , los genéricos en Scala están bien soportados, aumentando la utilidad y la extensibilidad.

  • Preciso : Scala es preciso debido a sus estrictas restricciones. Esto significa que, la mayoría de las veces, los problemas se detectarán durante la compilación en lugar de después de la implementación completa.

¿Por qué Scala? ¿Por qué no Java?

Para muchos desarrolladores, la cuestión de si utilizar o no Scala o Java es una cuestión de conveniencia. "Sé Java, y Scala se parece mucho a Java ... entonces, ¿por qué debería cambiar?" Es una pregunta legítima, y ​​una que tiene una respuesta simple: Scala hace algunas cosas extremadamente bien que Java no hace, y en menos espacio .

Scala es, para citar al ingeniero de sistemas de Motorola Brian Tarbox , "transformacional en lugar de procedimental". Mientras que Java explica al sistema cómo hacer algo, Scala ofrece pasos simples para realizar esa misma función sin verbosidad. Podría decirse que es más limpio y, por lo tanto, más simple, al tiempo que logra lo mismo.

Toma esta simple comparación. Creemos una lista de cadenas, utilizando un lenguaje de uso estándar. (Hay muchas formas de acortar el código Java, pero muchas no son compatibles o no están en uso estándar, por lo que no se discutirán aquí).

La versión de Java :

List list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");

Compare esto con la versión de Scala :

val list = List("1", "2", "3", "4", "5", "6")

Si bien es posible que algunos no vean esto como una reducción lo suficientemente grande en el espacio, tenga en cuenta que a medida que el código se expande a longitudes cada vez mayores, la importancia de la compacidad ciertamente se suma. Como otro ejemplo, creemos un fragmento que se basa en una clase de usuario predefinida y devuelve todos los productos que ha pedido ese usuario.

La versión de Java :

public List getProducts() {
    List products = new ArrayList();
    for (Order order : orders) {
        products.addAll(order.getProducts());
    }
    return products;
}

La versión Scala :

def products = orders.flatMap(o => o.products)

Esa es una gran diferencia, de siete líneas a una.

Consulte también: Creación de API en la JVM con Kotlin y Spark

Métodos diferentes y más eficientes

La reducción de la complejidad es ciertamente valiosa, pero hay algo más fundamental entre Java y Scala. Como un ejemplo más para demostrar la reducción de la complejidad, el Tarbox citado anteriormente creó el siguiente método de procesamiento de registros tanto en Java como en Scala :

La versión de Java :

import java.io.BufferedReader;
   import java.io.DataInputStream;
   import java.io.FileInputStream;
   import java.io.InputStreamReader;
   import java.util.HashMap;
   import java.util.Iterator;
   import java.util.Map;
   import java.util.Scanner;
   import java.util.TreeMap;
 import java.util.Vector;
  void getTimeDiffGroupedByCat() {
  	FileInputStream fstream = new FileInputStream("textfile.txt");
  	DataInputStream in = new DataInputStream(fstream);
 	BufferedReader br = new BufferedReader(new InputStreamReader(in));
  	String strLine;
  	Long thisTime;
  	HashMap lastCatTime = new HashMap();
  	TreeMap> catTimeDiffs
	       	= new TreeMap>();
  	while ((strLine = br.readLine()) != null)   {
          	Scanner scanner = new Scanner(strLine);
          	thisTime = scanner.nextLong();
           	String category = scanner.next();
           	Long oldCatTime = lastCatTime.put(category, thisTime);
           	if(oldCatTime != null) {
                 	if(catTimeDiffs.get(category) == null) {
                   	catTimeDiffs.put(category, new Vector());
                	}
                	catTimeDiffs.get(category).add(thisTime - oldCatTime);
           	}
   	}
   	for(Map.Entry> thisEntry:
	       	catTimeDiffs.entrySet()) {
           	System.out.println("Category:" + thisEntry.getKey());
           	Iterator it = thisEntry.getValue().iterator();
           	while(it.hasNext()) {
                   	System.out.println(it.next());
                   	if(it.hasNext())
                           	System.out.print(", ");
           	}
   	}
  }

Este código crea un HashMap simple que contiene las marcas de tiempo con clave, organizándolo por categoría. Estos valores luego se comparan con marcas de tiempo anteriores del HashMap, devolviendo la diferencia como un vector de categoría adjunto de diferencias de tiempo en el TreeMap generado. Las líneas 28 a 36 imprimen estos resultados en una serie de listas separadas por comas.

La versión Scala :

import Source.fromFile
	def getTimeDiffGroupedByCat = {
  	val lines = fromFile("file.txt").getLines
   	val tuppleList = for(oneLine <- lines) yield {val z = oneLine.split
	      	(' '); (z(0).toInt, z(1)) }
   	for(groupedList <- tuppleList.toList.groupBy(oneTuple =>
	      	oneTuple._2)) {
      	val diffList = for(logPairs <- groupedList._2.sliding(2)) yield
	         	(logPairs(1)._1 - logPairs(0)._1)
     	println(groupedList._1 + ":" + diffList.mkString(","))
	}
   }

Renunciando al hecho de que la versión de Scala es mucho menos detallada, sin duda una razón para adoptar Scala solo, hay algo mucho más importante aquí. Debido a que Scala es inmutable , el manejo se maneja de manera diferente en la versión de Scala, transformando los datos en listas en lugar de en los HashMaps de Java mutables.

Estas líneas se generan utilizando la función getLines, que luego se itera sobre la lista de líneas, ejecutando el código siguiendo la valoración del rendimiento. Este resultado luego se agrega a la variable tuppleList, que luego se agrupa usando groupBy, que después de varias manipulaciones adicionales sigue a oneTuple. 2 y logPairs (0). 1 definiciones, están impresas.

En pocas palabras, la versión de Scala maneja la misma función con menos código, de una manera más sucinta y con menos complejidad, al tiempo que permite una manipulación y escritura inmutables.

Banner básico-01

Rendimiento e integración de Scala

Spark es breve: fue diseñado para ser compacto y para llevar a cabo un rendimiento con bases de código relativamente pequeñas. Aunque Java hace esto hasta cierto punto, Scala mantiene este espíritu en su esencia misma. Scala es, en todos los sentidos, un lenguaje que da como resultado bases de código más pequeñas, procesamiento más eficiente y solución de problemas y diseño más fáciles.

A pesar de todos sus beneficios, Scala puede ser más complejo que la funcionalidad prevista. Por esta razón, algunos lo han rehuido. La complejidad que surge de la naturaleza de las interacciones de funcionalidad implícita del código a menudo puede hacer que la implementación de cifrado, transformación, autenticación, etc. sea más compleja de lo que sería en Java.

Dicho esto, el resultado final de esta complejidad es una simplicidad contraintuitiva en la base de código real. Una vez que se determina la funcionalidad y se concibe el mapa de funciones, esta complejidad se representa mediante muestras de código relativamente pequeñas y, por lo tanto, un procesamiento eficiente.

Conclusión

Scala y Java son dos lenguajes maravillosos. Sin embargo, como cualquier otro idioma, existen serias fortalezas y debilidades a considerar cuando se utilizan para el desarrollo. Si bien Java es la mejor opción para un desarrollador que está firmemente arraigado en la mentalidad de Java o tiene una gran experiencia en programación en el lenguaje, Scala es una alternativa maravillosa que ciertamente reduce la complejidad, al tiempo que permite una manipulación más compleja.

Por supuesto, esto es solo una parte de la ecuación: la integración de los sistemas y protocolos de seguridad , las metodologías de desarrollo de microservicios y la arquitectura API fundamental es tan importante como el lenguaje en el que se está desarrollando. Con una comprensión completa del lenguaje elegido y una visualización completa de los requisitos inherentes a su API, el desarrollo exitoso se convierte en un objetivo alcanzable.

Recursos

Los siguientes recursos pueden ayudar tanto a los programadores novatos como a los experimentados a obtener más información sobre Scala y Spark.

  • Introducción a Spark
  • Introducción a Scala
  • Especificación completa del lenguaje Scala
  • Creación de API en la JVM con Kotlin y Spark
  • Uso de Spark para crear API en Java

Publicar un comentario

0 Comentarios