Header Ads Widget

Ticker

6/recent/ticker-posts

Construyendo una API REST en Java y Scala usando Play Framework - Parte 1

 

construyendo-un-resto-api-en-scala-y-java-usando-play-framework-1

En esta serie de dos partes, exploramos Play Framework y vemos cómo se puede utilizar para desarrollar rápidamente API RESTful. En la primera parte, presentamos Play, que cubre las principales decisiones de diseño detrás de su arquitectura y las posibles razones para elegir este marco sobre otros. Terminaremos con una guía de configuración rápida y un ejemplo básico. Al final de esta primera parte, tendrá una idea de lo fácil que es configurar una API REST usando Play.

En la segunda parte , profundizaremos en las características de Play. Usaremos ejemplos del mundo real para mostrar cómo aprovechar las capacidades únicas de Play. Al final de la serie, debería tener un buen conocimiento del desarrollo de API usando Play con amplios recursos para construir su propia API REST.

Presentamos Play Framework 2

jugar framework-logo

Hasta ahora, en el blog, hemos analizado el uso del marco web Spark para diseñar API en Kotlin , Java y Scala . También es difícil hablar sobre la creación de API REST en la máquina virtual Java (JVM) sin mencionar Play Framework . Play es un marco web de código abierto construido en Scala y diseñado para desarrolladores de Java y Scala.

A pesar de la gran cantidad de marcos web Java que ya existían en ese momento (Spring MVC, JSF, Google Web Toolkit, Grails ...), el desarrollador francés Guillaume Bort se propuso construir Play Framework en 2007. Se inspiró en marcos para otros lenguajes de programación como Rails (para Ruby) y Django (para Python) que eran amigables para los desarrolladores y muy adecuados para la creación rápida de prototipos.

Una arquitectura RESTful

La arquitectura de Play es RESTful por defecto. En esencia, Play se basa en el patrón Modelo-Vista-Controlador . Cada punto de entrada, emparejado con un verbo HTTP, se asigna a una función de controlador. El controlador permite que las vistas sean páginas web, JSON, XML o casi cualquier otra cosa.

La arquitectura sin estado de Play permite el escalado horizontal, ideal para atender muchas solicitudes entrantes sin tener que compartir recursos (como una sesión) entre ellos. Está a la vanguardia de la tendencia de programación reactiva , en la que los servidores se basan en eventos y el procesamiento paralelo se utiliza para satisfacer las crecientes demandas de los sitios web modernos.

En determinadas configuraciones, Play permite E / S totalmente asíncronas y sin bloqueo en toda la aplicación. El propósito es alcanzar nuevas alturas en términos de escalabilidad en la web a través de una gestión eficiente de subprocesos y procesamiento paralelo, mientras se evita el 'infierno de devolución de llamada' que las soluciones basadas en JavaScript tienden a generar.

En esta primera parte de la serie Play Framework, veremos Play 2 en el contexto de la creación de servicios REST sin estado. Play también tiene un motor de plantillas HTML y todas las herramientas necesarias para crear aplicaciones web completas, pero nos centraremos en las funciones necesarias para crear una API.

Descarga nuestra guía de desarrollo gratuita

¿Por qué jugar Framework 2?

Play Framework fue creado para desarrolladores de Scala y Java , y la base de código se mantiene para seguir siendo una alternativa viable ya sea que use un idioma u otro.

El pragmatismo de Play es uno de sus activos, al igual que lo es para el lenguaje Scala. Los ciclos de iteración rápidos y el estilo de programación ágil permiten atraer a los fundadores de nuevas empresas, pero su familiaridad con los desarrolladores de Java / JVM lo convierte en una opción para el mundo corporativo y académico también.

Estas son algunas de las razones por las que los desarrolladores eligen Play:

  • Aprovecha la JVM, un entorno de ejecución popular y maduro, y todas las bibliotecas del ecosistema Java,
  • Atiende a una gran población de desarrolladores, que abarca software empresarial, academia y nuevas empresas,
  • Refuerza la seguridad de los tipos y fomenta el diseño orientado a objetos,
  • Para los desarrolladores de Scala, ofrece un excelente marco web basado en la programación funcional, un paradigma que garantiza la ausencia de efectos secundarios y promueve la concisión del código.
  • Es una excelente opción para el diseño de API primero (RESTful),
  • Tiene una comunidad activa (grupos de Google, complementos ...), aunque menos que los principales marcos web como Node.js.

Play favorece la convención sobre la configuración y no se necesitan archivos de configuración XML para comenzar a funcionar. Utiliza SBT para la gestión de dependencias y edificios. Tiene una característica popular de 'actualización automática' que permite a los desarrolladores probar problemas de compilación y tiempo de ejecución en el navegador sin reiniciar el servidor cada vez que cambia el código.

Play es liviano por diseño: muchas de las funciones que están integradas en la mayoría de los marcos web se han aislado y empaquetado como complementos. También es fácilmente extensible y permite múltiples casos de uso y escenarios de implementación, por ejemplo, como una aplicación web, el backend de una aplicación móvil o como parte de una arquitectura de microservicios .

Hay varias opciones de implementación . Varios proveedores de alojamiento en la nube, incluidos Heroku  y Jelastic , tienen soporte específico para Play y se puede implementar fácilmente en AWS Elastic Beanstalk , Google App Engine y Digital Ocean . Por supuesto, puedes alojar Play en tus propios servidores con la misma facilidad.

Como parte oficial y con soporte comercial de Lightbend (anteriormente Typesafe), la compañía detrás de Scala y Akka , Play viene con opciones para soporte de producción profesional, herramientas de monitoreo avanzadas y complementos IDE (incluido el Scala IDE oficial para Eclipse que incluye Play-specific caracteristicas). También significa que no desaparecerá pronto.

Muchas startups e instituciones de noticias famosas ahora usan Play; está especialmente presente en empresas donde la escalabilidad es primordial; LinkedIn , Coursera , Hootsuite , Klout , LendUp , The New York Times y The Guardian están usando Play para partes críticas de su arquitectura.

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

Un ejemplo básico

Ahora veamos algunos ejemplos de creación de una API REST impulsada por Play. Todos los ejemplos de las secciones siguientes estarán en Scala, aunque todo aquí también es posible en Java.

Play viene con un ejecutable llamado 'activador', que permite a los desarrolladores ponerse en marcha rápidamente . Crea una estructura de carpetas básica y proporciona una herramienta de línea de comandos (o una interfaz gráfica de usuario) desde la que puede compilar y ejecutar su aplicación Play, o volver a cargar su configuración.

No necesita crear nada especial para exponer una API REST; de forma predeterminada, Play admite servicios web RESTful al permitir que el desarrollador haga coincidir un verbo HTTP y un punto final con una función definida en un controlador personalizado a través de un archivo de 'rutas' flexible.

GET		/name				controllers.Application.getName

La ruta anterior asigna el punto final '/ nombre' y el verbo HTTP GET a la función getName del controlador de la aplicación. Cada vez que una solicitud HTTP entrante llega al servidor, se activa una acción, como se define en una función de controlador. Para atender la solicitud descrita en nuestro archivo de rutas, todo lo que tenemos que hacer es describir la función getName en el controlador de la aplicación:

package controllers

import play.api._
import play.api.mvc._

object Application extends Controller {

  def getName = Action {
  	Ok("Jim")
  }

}

Y ahí lo tenemos: una API REST simple que devuelve la cadena "Jim" cuando se solicita el punto final / name.

El archivo de rutas admite expresiones regulares para asignaciones flexibles . En el siguiente ejemplo, usamos una expresión regular para asignar un punto final a una función solo cuando la URL termina con una Cadena de 20 como máximo de longitud con .JPG o .PNG como extensión:

GET 	/pics/$name<\w{1,20}\.(jpg|png)>	controllers.Application.getPicture(name: String)
Aprenda a mejorar la experiencia de la API con Hypermedia

Tratar con JSON

Play tiene soporte nativo para JSON y ofrece varias opciones para desarrolladores que buscan analizar JSON en objetos del modelo de dominio.

Puede analizar y componer objetos JSON manualmente:

def parseJson(json: JsValue) = Action { implicit request => 
  val name = (json \ "name").asOpt[String].get
  Ok("name : " + name)
}

Pero la biblioteca JSON de Play permite convertir objetos JSON en instancias de clases de casos de Scala automáticamente.

La biblioteca JSON de Play admite el mapeo bidireccional entre objetos JSON y clases de casos de Scala. Para demostrarlo, definamos una clase Person con los siguientes atributos.

case class Person(name: String, country: String, id: Int)

Si recibimos un archivo JSON como el que se muestra a continuación,

{
	name: “Jim Davis”,
	country: “United Kingdom”,
	id: 44952
}

podemos leer fácilmente estos valores en una instancia de la clase de caso Person, usando los convertidores predeterminados de Play:

def parseJson(json: JsValue) = Action { implicit request =>
val person = json.read[Person] Ok("name : " + person.name) }

Probemos con un ejemplo del mundo real más complejo. Vamos a analizar un archivo JSON que representa un objeto Charge de la popular API de pagos Stripe . El objeto Charge es complejo y solo queremos mapearlo parcialmente a una clase de caso simple que se ajuste a las necesidades de nuestra aplicación.

En el siguiente ejemplo, creamos un mapeo entre un objeto JSON que representa un cargo de Stripe y una clase de caso Scala. Tenga en cuenta que no estamos mapeando todo el objeto JSON, solo las partes que nos interesan.

import play.api.libs.json._
import play.api.libs.functional.syntax._

case class StripeCharge(id: String, created: Long, amount: Int, status: String, currency: String, 
	refunded: Boolean, maybeFailureMessage: Option[String], stripeCustomer: String) {

	implicit val stripeChargeReads: Reads[StripeCharge] = (
	  (JsPath \ "id").read[String] and
	  (JsPath \ "created").read[Long] and
	  (JsPath \ "status").read[String] and
              (JsPath \ "amount").read[Int] and
      	  (JsPath \ "currency").read[String] and  
              (JsPath \ "refunded").read[Boolean] and  
              (JsPath \ "failure_message").readNullable[String] and 
              (JsPath \ "customer").read[String] 
             )(StripeCharge.apply _)

}

Ahora que hemos definido este mapeo personalizado, podemos llamarlo implícitamente cuando queremos convertir JSON en una instancia de esta clase Scala como lo hicimos antes. Esta vez usaremos json.validate en lugar de json.read. Esto nos permite gestionar posibles excepciones al analizar el objeto JSON.

json.validate[StripeCharge] match {
 case c: JsSuccess[StripeCharge] => {
    val charge: StriepCharge = c.get
    Logger.info("Successfully parse Stripe charge: " + charge.id)
  }
  case e: JsError => {
    Logger.info("Error parsing Stripe charge: " + e.getMessage)
  }
}

Así como puede escribir lecturas implícitas para convertir JSON en objetos Scala, también puede crear escrituras para convertir objetos en JSON.

Continúe con la Parte 2 para obtener más información

En la Parte 2 de esta serie , veremos cómo Play maneja los servicios web síncronos y asincrónicos, cómo ofrece herramientas para combinar y agregar cálculos arbitrarios para crear aplicaciones de backend ricas, qué opciones ofrece para la persistencia y transmisión de datos, y nosotros ' Revisaremos una lista de consejos y trucos para aprovechar al máximo Play. Suscríbase a nuestro boletín para asegurarse de no perderse la Parte 2 de esta serie sobre el uso de Play Framework.

Publicar un comentario

0 Comentarios