Mostrando las entradas con la etiqueta play. Mostrar todas las entradas
Mostrando las entradas con la etiqueta play. Mostrar todas las entradas

martes, 27 de agosto de 2019

Inyección de dependencia de tiempo de compilación

Spring proporciona un mecanismo para la inyección de dependencias en tiempo de ejecución, es decir, la inyección de dependencias donde las dependencias no están conectadas hasta el tiempo de ejecución. Este enfoque tiene ventajas y desventajas, las principales ventajas son la minimización del código repetitivo, la principal desventaja es que la construcción de la aplicación no se valida en tiempo de compilación.

Un enfoque alternativo que es popular en el desarrollo de Scala es utilizar la inyección de dependencia de tiempo de compilación. Esta técnica se puede lograr mediante la construcción manual y el cableado de dependencias. Existen otras técnicas y herramientas más avanzadas, como herramientas de cableado automático basadas en macros, técnicas de cableado automático implícito y varias formas del cake pattern.

Inyectar dependencias en tiempo de compilación permite aprovechar el compilador para verificar que cada controlador en su aplicación tenga acceso a todos los componentes que necesita. Eso significa que no necesita preocuparse por los errores de tiempo de ejecución que causan bloqueos y una mala experiencia para sus usuarios. De hecho, la DI en tiempo de compilación (y la tipificación estática en general) pueden reducir la necesidad de un subconjunto de tipos comunes de pruebas unitarias.

El uso de parámetros de constructor es un enfoque simple y directo para definir dependencias en tiempo de compilación. Veamos un ejemplo del framework play:

class Controller( val controllerComponents: ControllerComponents,
  userModel: UserModel) extends BaseController {

  def user() = Action {
   request => Ok(Json.toJson(userModel.getUsernames()))
  }
}

Se puede decir que la siguiente clase "depende de" una instancia de ControllerComponents y una instancia de UserModel. Esto es tan simple como especificar dependencias. No hay magia, solo dices qué componente quieres y lo obtienes. Configurar cómo se proporcionan las dependencias requiere un poco más de trabajo. Aquí es donde entra el cargador de aplicaciones de play.

class Loader extends ApplicationLoader {
  def load(context: Context): Application = {
    LoggerConfigurator(context.environment.classLoader).foreach {
      _.configure(context.environment)
    }
    new Components(context).application
  }
}

class Components(context: Context) extends BuiltInComponentsFromContext(context) {
  override lazy val httpFilters = Nil
  Lazy val userModel: UserModel = new UserModel()
  lazy val controller: Controller = new Controller(controllerComponents, userModel)
  lazy val router: Router = new Routes(httpErrorHandler, controller)
}

La clase Loader se requiere principalmente para garantizar que la aplicación esté configurada correctamente cuando se carga. La inyección de dependencias ocurre en la clase Componentes. Una vez más, no hay magia aquí: simplemente crea y pasa instancias a componentes que las necesitan. BuiltInComponentsFromContext proporciona un puñado de componentes de Play predeterminados que son útiles. En este caso, uso el componente ControllerComponents para nuestro controlador y un HttpErrorHandler para el constructor de Rutas.

Para aplicaciones simples, la inyección manual de dependencias es bastante simple. Sin embargo, incluso en aplicaciones simples, agregar una dependencia a un controlador requiere que modifique tanto el controlador como el cargador de aplicaciones. Este proceso se ve exacerbado por el constructor de Rutas que genera Play. Cada clase a la que haga referencia en conf / routes se traducirá en un parámetro constructor del objeto Routes. Eso significa que agregar una clase de controlador requiere que crees una instancia de la clase y la pases explícitamente al constructor de Rutas. Para empeorar las cosas, si reordena su archivo conf / routes o agrega una nueva ruta en algún lugar en el medio, su objeto Routes generado tendrá un nuevo orden para sus parámetros de constructor, y tendrá que arreglarlo manualmente también.

La inyección manual en tiempo de compilación no es escalable y creará mucho trabajo adicional en aplicaciones más complejas. Aquí es donde entra MacWire.

MacWire es una macro muy ligera que genera automáticamente llamadas de constructores. Eso es casi todo lo que hace (está bien, tiene algunas otras características, pero solo nos importa esta por ahora). Usando MacWire, cambié la clase de Componentes anterior a la siguiente:

class Components(context: Context) extends BuiltInComponentsFromContext(context) {
  override lazy val httpFilters = Nil
  lazy val userModel: UserModel = wire[UserModel]
  lazy val controller: Controller = wire[Controller]
  lazy val router: Router = {
    val prefix = "/"
    wire[Routes]
  }
}

Notarás dos cambios importantes.

Primero, todas las llamadas "nuevas" han sido reemplazadas por wire [ClassName]. Esta es la macro que genera las llamadas "nuevas". Para ello, examina el constructor predeterminado para la clase especificada y luego busca valores del mismo tipo en el ámbito actual. El wire [Controlador] se expandirá a un nuevo Controlador (controllerComponents, userModel). Ese es exactamente el mismo código que escribimos manualmente arriba. Wire sigue las reglas normales de alcance con las que ya está familiarizado en Scala. Si hay varias instancias que cumplirán una dependencia, el cable fallará en tiempo de compilación diciendo que no puede decidir qué instancia usar. Tendrá que resolver esta ambigüedad manualmente. MacWire proporciona calificadores para simplificar este proceso cuando sea necesario.

En segundo lugar, la definición de enrutador cambió. El constructor predeterminado de Rutas requiere un argumento de prefijo de cadena, mientras que el constructor utilizado manualmente en nuestro ejemplo original anterior no es el constructor predeterminado y no requiere este argumento. Envolví el prefijo en el alcance del bloque de la llamada por cable para no filtrar accidentalmente el prefijo en otros componentes que podrían necesitar un parámetro de cadena. En proyectos más grandes, esto se vuelve más valioso. En este ejemplo, todo habría funcionado bien si definiera el prefijo fuera del bloque Router.

Ahora, agregar una dependencia (o eliminar una dependencia) de un controlador solo requiere que modifique el controlador en sí. Entonces, si necesita acceso a la configuración de la aplicación, puede agregar un parámetro de constructor con el tipo Configuración al controlador y, como por arte de magia, inyectará un objeto de Configuración. Aún mejor, agregar, eliminar o reordenar rutas en conf / routes se vuelve mucho más fácil porque ya no tiene que preocuparse por el orden de los parámetros de Rutas o cualquier cosa más allá de las clases específicas para las que necesita proporcionar instancias.

Una última nota sobre MacWire: se debe usar lazy val. Esto permite especificar dependencias complicadas sin preocuparse por el orden de inicialización entre los diferentes componentes. Todos se crearán a pedido y evitará posibles excepciones de puntero nulo. También puede usar defs si prefiere que cada clase que depende de su def obtenga una nueva instancia en lugar de una instancia compartida.

Y me quedo relargo el post en otro vamos a ver el cake pattern.


domingo, 2 de julio de 2017

miércoles, 22 de octubre de 2014

Node.js vs Play

Un muy buen resumen sobre las diferencias de estos Frameworks y muchas cosas que no sabia, por ejemplo que coursera esta hecho en play.


miércoles, 25 de junio de 2014

Documetando APIs Rest con Swagger


Te imaginas un javadoc de tus servicios REST? Swagger es eso y mucho más dado que es una herramienta extremadamente útil para describir, producir, consumir y visualizar APIs RESTful. El principal objetivo de este framework es enganchar el sistema de documentación con el código del servidor para que esté sincronizado a cada cambio. Casi documentamos al mismo tiempo que creamos la implementación.

Swagger está desarrollado de tal modo que podemos usar Scala, Java, Javascript, Ruby, PHP o ActionScript para generar toda la documentación y su sandbox correspondiente. Además, existen distintos módulos para enganchar a nuestros proyecto Node.js, Grails, Scala Play, Spring MVC, Symfony o Ruby, entre otros muchos.

Los usuarios de las APIS también son beneficiados ya que proporciona una interfaz visual a modo de sandbox donde podemos testear la llamadas del API, además de consultar su documentación. Podéis echar un vistazo a un ejemplo de la web que genera Swagger a partir del código de nuestra API con los métodos, parámetros y modelos de JSON que devuelve.

Swagger es perfecto para tener la documentación de nuestras APIs a punto y brindarle un servicio más a los clientes con ejemplos.

The Swagger™ Specification: https://github.com/wordnik/swagger-spec
Swagger™ Demo: http://petstore.swagger.wordnik.com/
Downloads: https://github.com/wordnik/swagger-core/wiki/Downloads

domingo, 6 de abril de 2014

Show Off. Get Proof. Convince Your Boss.


No soy asiduo de hacer publicidad a empresas pero quiero recomendarles la pagina de Typesafe.

Go Typesafe es un conjunto de recursos para ayudar a convencer a sus compañeros para utilizar la plataforma reactive de Typesafe: Play Framework, Akka y Scala.

Dejo link:
http://go.typesafe.com/

jueves, 2 de enero de 2014

Typesafe Activator

Estoy haciendo el curso de play que postee hace rato. Y la verdad quede asombrado con el activator de typesafe. Es muy bueno! es como maven++, una genialidad.

Lo primero que tenemos que hacer es descargarnos Activator, luego descomprimirlo en una carpeta por ejemplo /opt/activator

Luego ejecutamos:

./activator ui

Lo que estamos haciendo es ejecutar activator de forma gráfica. Luego tenemos que ir a nuestro browser a la URL : http://localhost:8888

Llenamos los datos y elegimos el template:


Esperamos que se cree el proyecto...

Luego nos aparece un menú que nos permite compilar la aplicación, generar los archivos para una IDE (estilo mvn eclipse:eclipse) correr la aplicación, etc.



Entre otras cosas se puede editar código:


También podemos correr los test y correr la aplicación:




Es como un maven con interfaz gráfica, muy bueno!

Dejo link:
http://typesafe.com/activator

lunes, 16 de diciembre de 2013

Play Framework for Java Developers


Typesafe creo un curso online gratuito para aprender play para desarrolladores Java. El objetivo es aprender aplicaciones Reactive con Play Framework.

Esta es una buena oportunidad para aprender play y interiorizarse de los conceptos para hacer hacer aplicaciones reactive.

Dejo link:
https://typesafe.com/how/online-training?utm_medium=email&utm_source=Act-On+Software&utm_content=email&utm_campaign=Announcing%20Typesafe%E2%80%99s%20New%20Online%20Trainings&utm_term=Play%20Framework%20for%20Java%20Developers

sábado, 16 de marzo de 2013

Primeros pasos con Play! Part 5

Y luego de un descanso seguimos aprendiendo play framework. Recuerden que nos habíamos quedado acá:

http://emanuelpeg.blogspot.com.ar/2013/02/primeros-pasos-con-play-part-4.html

Nos habíamos quedado en crear el modelo de Algo:

package models

case class Algo (id: Long, nombre: String, descripcion: String)

object Algo {
 
  def all(): List[Algo] = Nil
 
  def create(nombre: String, descripcion: String) {}
 
  def delete(id: Long) {}
 
}

Bueno creamos la case class Algo que nos sirve de modelo y luego un Objeto que va a realizar las tareas de listar, crear y borrar. Por ahora es un Objeto Dummy, onda que no hace nada pero luego vamos a implementar su interacción con la base de datos.

Para el que no este familiarizado con case class de scala puede leer esto: http://www.scala-lang.org/node/107.

Ahora vamos a hacer la pagina principal:


@(algos: List[Algo], algoForm: Form[String])

@import helper._

@main("Todo list") {
   
    <h1>@algos.size algo(s)</h1>
   
    <ul>
        @algos.map { algo =>
            <li>
                @algo.nombre
               
                @form(routes.Algo.delete(algo.id)) {
                    <input type="submit" value="Delete">
                }
            </li>
        }
    </ul>
   
    <h2>Add a new Algo</h2>
   
    @form(routes.Algo.newAlgo) {
       
        @inputText(algoForm("Nombre"))
       
        @inputText(algoForm("Descripcion"))
       
        <input type="submit" value="Create">
       
    }
   
}

Vamos a explicar un poquito, al principio declaramos una lista de Algo y un formulario; luego imprimimos cuantos algos hay y generamos un listado; permitiendo que se puedan eleminar; y para finalizar permitimos crear nuevos algos.

También importamos helper._ el cual nos ayuda a la creación de formularios. Normalmente un formulario crea un <form> de html.

Ahora vamos al controller a decirle que muestre nuestra nueva pagina:



package controllers

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

import play.api.data._
import play.api.data.Forms._

object Algo extends Controller {

  def index = Action {
    val algoForm = Form(
      "Nombre" -> nonEmptyText)
    Ok(views.html.algoIndex(models.Algo.all() ,algoForm))
  }

  def newAlgo = TODO

  def delete(id: Long) = TODO

}


Como vemos hemos hecho un formulario y le dijimos que nombre es requerido. Además que vaya a nuestra pagina.

Si vamos a http://localhost:9000/algo veremos la siguiente pagina:



Hermosa salvo porque todavía no guarda en la base de datos... Pero esto será en el próximo post!


lunes, 25 de febrero de 2013

Primeros pasos con Play! Part 4


Seguimos con Play!

Vamos a modificar el ejemplo, primero vamos a modificar la clase Application.scala de la siguiente manera:

package controllers

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

object Application extends Controller {
 
  def index = Action {
    Ok("Hola!")
  }
 
}





Estamos devolviendo “Hola!” que es texto plano. Pero si nos equivocamos y ponemos así:

def index = Action {
    Ok("Hola!)
}

Play nos ayuda, nos indica donde esta el error:


Bueno vamos a hacer un ABM de algo, primero vamos a modificar el archivo conf/routes de la siguiente manera:

# Algo page
GET     /algo                          controllers.Algo.index
GET     /algo/new                   controllers.Algo.new
GET     /algo/:id/delete            controllers.Algo.delete(id: Long)

Ahora vamos hacer el nuevo action llamado Algo.scala que va a ser así:

package controllers

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

object Algo extends Controller {
 
  def index = TODO
 
  def newAlgo = TODO
 
  def delete(id: Long) = TODO
 
}

Dejamos los métodos en TODO, es decir que lo vamos a hacer más adelante. Si corremos el servidor y vamos a http://localhost:9000/algo vemos lo siguiente:


Para que se entienda TODO es un método que devuelve un action es así:

  val TODO = Action {
    NotImplemented[play.api.templates.Html](views.html.defaultpages.todo())
  }

Por lo tanto cuando busca controllers.Algo.index devuelve al action TODO. Pero ahora rápidamente vamos a escribir el model de Algo. Pero esto lo vamos a ver en el próximo post...


sábado, 23 de febrero de 2013

Primeros pasos con Play! Part 3


Siguiendo con los posts:

http://emanuelpeg.blogspot.com.ar/2013/02/primeros-pasos-con-play.html
http://emanuelpeg.blogspot.com.ar/2013/02/primeros-pasos-con-play-part-2.html

Tenemos que bajarnos Scala-IDE del siguiente link:
http://scala-ide.org/download/milestone.html y tenemos que bajar eclipse del siguiente link: http://www.eclipse.org/downloads/ (juno) y si no queremos usar la ultima versión podemos bajar Indigo : http://www.eclipse.org/downloads/packages/release/indigo/sr2

Descomprimimos el empaquetado y ya tenemos el IDE funcionando.
Ahora vamos a importar el proyecto. Para ello vamos a la carpeta raíz del proyecto y ponemos:

play eclipse

Entonces desde eclipse hacemos import... → “exiting projects into workspace” con esto tenemos nuestro proyecto en eclipse.

Ahora esta todo configurado, podemos programar libremente.

Vamos a ver como se muestra la pagina cuando corremos la aplicación. En conf/routes se define el punto de entrada de la aplicación; sería como un struts.xml en struts. En este archivo podemos ver algo como esto:

# Home page
GET     /                           controllers.Application.index

Esto quiere decir que si vamos a / va a llamar al controlador Application al método index. Si vemos el action podemos ver lo siguiente:

package controllers

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

object Application extends Controller {
 
  def index = Action {
    Ok(views.html.index("Your new application is ready."))
  }
 
}

Como pueden ver este controller devuelve el objeto Ok que es un Action. Este action indica que todo salio bien, es decir que termino con código 200. Con el método views.html.index(message: String), se esta llamando a las vista index.scala.html. Si abrimos este archivo podemos ver:

@(message: String)

@main("Welcome to Play 2.1") {
   
    @play20.welcome(message)
   
}

La plantilla permite mezclar contenido html con declaración de Scala, las declaraciones de scala comienzan con el @.

Por ahora no vamos a modificar nada pero en el próximo post, ya lo verán...


martes, 12 de febrero de 2013

Primeros pasos con Play! Part 2


Bueno vamos a hacer la primera aplicación con scala. Que necesitamos??

  • Tener play instalado como lo indica aquí
  • Tener Scala-IDE que se puede bajar de aquí o algún editor como vi, nano, etc.

En el comando escribimos play new nombreDeLaAplicacion

Ahora se va a ejecutar un programa interactivo que nos va a preguntar el nombre del proyecto y si vamos usar java o scala. Luego de finalizar hacemos ls para verificar que se creo la carpeta del proyecto.

Si hacemos cd nombreDeLaAplicacion podemos ver los siguientes directorios:

app: se encuentra el core de la aplicación; se encuentran los objetos del modelo, controles y vistas. Aquí se encuentran los .scala
conf: se encuentran las configuraciones, application.conf, routes y archivo de internacionalización.
project: se encuentran los scripts de creación estos se basan en sbt.
public: contiene todos los recursos publicos como imagenes, css, javascripts, etc.
test: se encuentran todos los test que se escriben como especificaciones Specs2

Ojo play utiliza UTF-8 como única codificación. Por lo tanto todo tiene que estar acorde a esta codificación.

Ahora podemos utilizar la consola play ejecutando el comando play dentro del directorio del proyecto.

play
(demora un rato)
run

Con run estamos corriendo el ejemplo. Si todo fue bien van a poder ver la linea:

[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000

Ahora vamos al browser (cual quiera) y vamos a la url: http://localhost:9000/

Y va a salir una pagina de play. Que esto? Nuestra aplicación funcionando!!

Que sucedió? Por qué me muestra esta pagina? Lo que sucede es que existe un archivo llamado conf/routes el cual define todos los accesos a la aplicación. Es decir con que url llegas a que pagina. Existe una linea así:

GET     /       controllers.Application.index

Lo que indica es que con / vamos a el controlador Application al método index. Si hacemos un cat de app/controllers/Application.scala podremos ver:

cat  app/controllers/Application.scala

package controllers

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

object Application extends Controller {
 
  def index = Action {
    Ok(views.html.index("Your new application is ready."))
  }
 
}

Como se puede ver el controlador devuelve un Action el cual maneja las respuestas del pedido del browser. Si el resultado de la petición es 200(ok) el Action devuelve la vista index. Esta vista se puede ver haciendo: cat app/views/index.scala.html

@(message: String)

@main("Welcome to Play 2.1") {
   
    @play20.welcome(message)
   
}

Como podemos ver recibe como parámetro un string (message) y con el imprime la pagina de bienvenida de play.
Antes de hacer una modificación vamos a configurar Eclipse, pero esa es otra historia...

to be continued ...

Primeros pasos con Play!



Tengo muchas ganas hace rato de aprender play y grails, pero por cuestiones de tiempo se me hacia imposible. Ahora tome la convicción de hacerme tiempo y aprender estos frameworks!

Voy a empezar con play y voy a desarrollar en scala. La idea es hacer el post paso por paso. Abrer que sale.

Primero voy a la pagina de play! (http://www.playframework.com/) y descargo el framework del siguiente link: http://downloads.typesafe.com/play/2.1.0/play-2.1.0.zip

Luego de descargar play-2.1.0.zip lo descoprimimos, yo como uso linux lo voy a descomprimir en /opt.

mv play-2.1.0.zip /opt
cd /opt
unzip play-2.1.0.zip
rm play-2.1.0.zip

La pagina oficial dice que no hay que instalarlo en /opt dado que es necesario tener permisos especiales. Esto lo podemos solucionar con chmod aunque no es el mejor camino.

Chmod 777  play-2.1.0 -R

Ahora me voy a fijar que java tengo instalado, dado que tiene que ser java 6 o superior.

java -version

Si no tuviera java 6 o superior debería instalarlo.

Ahora agregamos a play a nuestro PATH. Yo lo voy a agregar a mi .profile

cd /home/miUsuario
nano .profile

Y agrego las siguientes lineas:

export PLAY=/opt/play-2.1.0
export PATH=$PATH:$PLAY

Y guardo. Ahora a actualizar las variables de entorno.

source ~/.profile

Y con el comando env vemos las variables de entorno. Si todo esta bien probar si play funciona:

play help

Ahora tenemos play instalado. A crear una aplicación pero esto va a ser en un próximo post.

To be continued…

sábado, 9 de febrero de 2013

Play 2.1 introduce CDI y modularidad


Play 2.1 se viene con inyección de dependencia y modularidad, será el primer trabajo de Rod Johnson?

El framework para hacer aplicaciones de forma rápida anuncio que su próxima versión soportará CDI y modularidad. De esta forma se va a poder inyectar dependencias con anotaciones. A la vez van a dividir el framework en modulos que tengan mínima dependencia entre ellos.

Se viene con todo play!!

jueves, 18 de octubre de 2012

Groovy o Scala esa es la cuestión?


Dos lenguajes están haciendose famosos en la plataforma Java, Groovy y Scala; los dos son similares pero tienen diferencias importantes; que son buenas saberlas antes de elegir uno o otro.

Lo principal a mi entender que impulso a Groovy fue Grails fue el caballo de batalla y que le hizo muy buena publicidad al lenguaje. En cambio Scala no tenia un framework de desarrollo ágil que lo impulsara hasta el framework Play! 2. Si bien Grails esta super maduro, play tiene una comunidad muy buena, Por lo tanto podemos decir que en este punto es empate.


Como semejanza los dos lenguajes corren sobre la JVM, con interoperabilidad con toda la plataforma. Los dos son orientados a objetos pero Scala también es funcional y los dos tienen closures. Además los dos permiten un sistema de reutilización con mixins.  

Los dos lenguajes soportan aplicación parcial de una función y curring, pero el uso de estas caracteristicas es más natural en Scala. 

Groovy es un lenguaje dinámicamente tipado, esto puede ser bueno o malo depende de como lo veamos; además Groovy soporta dynamic meta-programming. 


Scala es un lenguaje estáticamente tipado por lo tanto no soporta dynamic meta-programming, es este punto Scala es más parecido a Java pero Scala cuenta con un sistema de tipos más sofisticado que Java. Algo que también hace la curva de aprendizaje más empinada.


Groovy es sintácticamente más parecido a Java pero semánticamente se ve la influencia que tuvo Ruby.

Scala  sintácticamente se ve la influencia de Java y Ruby, pero semánticamente fue influido por Java, SML, Haskell y gBeta.

Scala optimiza las funciones recursivas esto tiene gran importancia en el paradigma funcional pero no tiene tanta importancia en la programación imperativa.

Los dos tienen por defecto evaluación ansiosa o  eagerly; sin embargo Scala permite call-by-name y lazy evaluation. En Groovy se puede emular call-by-name con clousures.

Scala no tiene el concepto de campos o clases estáticas, utiliza singletones; en cambio groovy, si utiliza statics.

Estas son las diferencias más importantes, que tenemos que tener en cuenta cuando escogemos uno o el otro...




miércoles, 14 de marzo de 2012

Play framework 2

Finalmente se anuncio de play framework 2, con nuevas novedades y una integración completa con scala.

Dejo link del anuncio y la nueva web:

http://blog.typesafe.com/introducing-play-20
http://www.playframework.org/

martes, 14 de febrero de 2012

Documentación completa de Play Framework disponible en español


Me llego el siguiente mail de la gente de play, una gran noticia:

"Finalmente hemos concluido la traducción de la documentación de Play
Framework. Pueden consultarla en http://playdoces.appspot.com/

Hace apenas tres meses anunciábamos en esta lista que junto con varios
colegas iniciábamos la traducción de la documentación de Play
Framework, y al mismo tiempo invitábamos a todos los usuarios de este
framework a sumarse a la tarea.

Hoy, mientras nos preparamos para el lanzamiento de play 2.0, gracias
a la colaboración de colegas de América Latina y España ya podemos dar
por concluida la traducción de toda la documentación del sitio de play
Framework.

Aquí tienen los links:

Página principal: http://playdoces.appspot.com/

Si vives en alguno de los países a quienes google restringe el acceso
a las aplicaciones de Google Application Engine (¿qué habrá pasado con
el lema de “No seas malo”?), también tenemos una copia del sitio
alojada en openshift: http://playdoces-opensas.rhcloud.com/

Anuncio de la versión 2.0 de play: http://playdoces.appspot.com/2.0

Hola mundo en play: http://playdoces.appspot.com/documentation/latest/firstapp

Tutorial completo de play: una aplicación completa paso a paso:
http://playdoces.appspot.com/documentation/latest/guide1

y muchos artículos más que pueden encontrar en
http://playdoces-opensas.rhcloud.com/documentation/latest/home

También pueden ver el anuncio en el blog:
http://playlatam.wordpress.com/2012/02/14/documentacion-completa-de-play-framework-disponible-en-espanol/

Queremos agradecer a @rodriguezlaurag y @mfmontanari de Argentina,
@gualtrapa de España, @pjquero de Venezuela and @alfonsokim de México,
y también a los desarrolladores de la traducción japonesa del sitio de
Play, @garbagetown y @ikeike443, cuyo trabajo forkeamos
descaradamente.

Esperamos que nos ayuden a difundir esta noticia y que esta iniciativa
ayude a impulsar el uso de Play en los países de habla hispana.

Saludos

Sas (@develsas)"



Felicitaciones!! 

viernes, 27 de enero de 2012

Con Play framework desarrollar aplicaciones web con Java y Scala... ¡vuelve a ser divertido!

Con Play framework desarrollar aplicaciones web con Java y Scala... ¡vuelve a ser divertido! es el titulo de la web en español de play; si!

Los usuarios de play decidieron traducir toda la documentación es español y colgarla en la web.

Dejo los links:
http://playdoces.appspot.com/
http://playdoces-opensas.rhcloud.com/