RatPack: Servicios REST fácil y rápido

Si alguna vez han tenido que implementar un servicio web usando REST, sabrán que hay muchas opciones para hacerlo. Spring tiene facilidades para implementarlos, hay estándares para realizarlos, y por supuesto hay una gran cantidad de frameworks que pueden estar dedicados a implementar servicios de este tipo o que son para aplicaciones web pero además pueden usarse para implementar servicios REST.

Una opción muy sencilla para REST es RatPack, un framework bastante ligero para hacer servicios REST como scripts en Groovy.

Con RatPack, simplemente definimos los servicios que queremos implementar, en un script de Groovy, y el framework se encarga de lo demás: el servicio se ejecutará como un servlet dentro de Jetty, despachando las peticiones HTTP a los URL's que nosotros hayamos definido.

Los scripts son muy sencillos. Un ejemplo de "hola mundo" en RatPack:

get('/') {
  "Hola, Mundo!"
}

Para ejecutarlo, necesitamos tener en nuestra ruta de ejecutables el script ratpack y entonces simplemente lo ejecutamos con la ruta al script:

ratpack holamundo.groovy

Por default, RatPack recibe peticiones en el puerto 5000, pero esto es configurable. Si apuntan su navegador a http://localhost:5000/, en su navegador aparecerá el texto Hola, Mundo!.

Por supuesto, se pueden recibir parámetros, de varias maneras. La manera REST es por supuesto como parte del URL, pero también se pueden mandar parámetros en un POST o en un GET. Por ejemplo:

get('/saluda1/:nombre') {
  "Hola, ${urlparams.nombre}!"
}
post('/saluda2') {
  "Hola ${params.nombre}!"
}

Para activar el primer servicio, podemos simplemente usar http://localhost:5000/saluda1/Enrique y obtendremos la cadena Hola, Enrique!; para activar el segundo servicio necesitamos hacer un HTTP POST al URL http://localhost:5000/saluda2 enviando como datos en el POST algo como nombre=Enrique, para obtener el mismo resultado.

Se pueden definir servicios usando los 4 verbos estándar de REST: get, post, put y delete. En teoría, además se pueden definir verbos personalizados; haciendo pruebas me di cuenta que no es así, pero una de las grandes ventajas del open source es el acceso al código y la libertad de modificarlo, de modo que pude implementar esta funcionalidad sin complicarme demasiado en mi copia del código, y ya envié los cambios al autor por si los quiere integrar a la versión oficial. Entonces, se puede registrar una ruta utilizando un verbo personalizado, por ejemplo:

register('saluda', '/:nombre') {
  "Hola, ${urlparams.nombre}!"
}

Para que esto funcione, se necesita un cliente de HTTP que pueda enviar verbos además de POST y GET. Una opción es hacer telnet al puerto 5000 y teclear:

SALUDA /Enrique HTTP/1.0 (doble ENTER)

y se obtendrá el saludo Hola, Enrique!.

Se pueden registrar rutas con varios parámetros, no solamente uno, y el valor de cada parámetro se obtiene del mapa urlparams. El mapa params sirve para obtener los valores que se recibieron en el query string del URL o como datos de un POST y ya vienen decodificados.

Se tiene también acceso a los encabezados y otros valores; hay un mapa headers que contiene todos los encabezados de la petición HTTP. Las variables request y response nos dan acceso completo a la petición y respuesta del servlet, lo cual es útil por ejemplo para recibir y contestar datos como una imagen, manejando directamente los streams.

Se pueden usar también plantillas. Por ejemplo, se puede crear un archivo hola.html con lo siguiente:

<html>
<head><title>Saludo</title>
<body>Hola, <b>${nombre}</b>!</body>
</html>

Para usarla, se invoca el método render con el nombre de la plantilla (la cual será buscada en el directorio desde donde se ejecutó ratpack) y opcionalmente un mapa con valores a sustituir. En este caso, se puede pasar directamente el mapa urlparams:

get('/saluda1/:nombre') {
  render "hola.html", urlparams
}

Y ahora al pedir http://localhost:5000/saluda1/javaMexico en el navegador, ya veremos un saludo formateado en HTML.

El script de Groovy puede contener referencias a otros componentes, se pueden tener variables fuera de la definición de las rutas (que a fin de cuentas son closures) y se pueden usar ahí. Esto nos permite por ejemplo definir un DataSource, o cargar un applicationContext de Spring, un cliente de web service, etc.

De entrada, yo he utilizado RatPack para prototipos de servicios, pero la verdad es que uno le va poniendo más código al script y al final ya no dan ganas de reescribirlo en otra cosa; si no es algo muy complicado, se puede levantar el script y simplemente configurar un proxy en el Apache httpd para redirigir las rutas pertinentes a RatPack.

Para mayor información se puede consultar , donde se hospeda el proyecto.

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de benek

Muy simple

Que bien! Que manera tan simple, ya es costumbre en las bibliotecas que surgen con Groovy.

Acabo de ver que ya integraron tu pull request, enhorabuena! https://github.com/bleedingwolf/Ratpack/commits/master

Imagen de ezamudio

ese es otro

Ese pull request fue hace tiempo, cuando le agregué SLF4J a RatPack, y lo actualicé a Groovy 1.8. Este es el pull request que contiene lo de los verbos custom, que hasta ahora sigue pendiente.

Imagen de greeneyed

Mola

Está bien tener opciones para poder hacer lo fácil fácil y sólo complicarse cuando hace falta. Y un kudos por ir más allá y no solo usar si no también colaborar con el Open Source.

S!

Ya lo había visto, pero donde

Esto se me hace demasiado familiar, de hecho cuando vi el primer ejemplo me pareció a node.js, pero esto ya lo había visto antes, estoy buscando...¡ya lo encontré! se me hizo parecidísimo a cherrypy, el punto a favor de RatPack es que tiene de su lado todas las librerías existentes en Java; aunque existe Jython, no sé si también esté disponible cherrypy ahí.

Se ve interesante, ver cómo los propuestas metidas por otros lenguajes están cada vez más penetrando en Java y siendo aceptadas gracias a Groovy, ejemplos de ello son Grails y RatPack; algo que ni JRuby ni Jython han logrado en mucho tiempo, Groovy lo está haciendo en un parpadear; se reconoce el mérito a pesar de que no me guste Groovy.

Imagen de skuarch

Perdon por la ignorancia

que es jetty ???

Imagen de neko069

@skuarch

Imagen de ezamudio

Jetty

De hecho es un proyecto de Eclipse.

http://www.eclipse.org/projects/project.php?id=rt.jetty

El proyecto en Codehaus son extensiones.

Imagen de bferro

Jetty y Tomcat

Ambos productos han estado compitiendo desde hace ya más de 10 años. Jetty comenzó a desarrollarse en Mortbay y hace unos pocos años pasó a formar parte de los proyectos de la fundación Eclipse.
Por su parte Tomcat fue desarrollado inicialmente en Sun por James Davidson, quien más tarde promovió que el proyecto se convirtiera en open source y lo cedieron a Apache. Davidson inventó Ant para esa transformación a código abierto.

Ambos productos Tomcat y Jetty son muy utilizados. Varias comparaciones consideran que la arquitectura de Jetty está más cerca de un sistema basado en componentes y más fácil de extender y de embeber en otras aplicaciones. La idea de Tomcat siempre fue la de brindar un sistema completo, aunque por supuesto que puede ser embebido.

Jetty ha ganado más espacio en los últimos años debido a que Tomcat dejó de ser la implementación de referencia de la tecnología de Servlets para "cederla" a Glassfish.

Grails promueve más Tomcat mientras que Google App Engine lo hace con Jetty, aunque en ambos casos se puede utilizar el otro.