lunes, 5 de diciembre de 2011

Servicios REST con Jersey y Ajax

Esta semana estuve de cursos en Indra Ciudad Real, por cierto, un grupo majísimo/panísima.

Hicimos un ejercicio de servicios REST con Java, Jersey, e invocación de estos con Ajax (una parte Prototype y otra jQuery) que no podía dejar pasar por alto. Utilizamos Eclipse como IDE, Derby como RDBMS y Glassfish como Servidor de Aplicaciones.

Les dejo los pasos en este artículo. El código completo lo pueden conseguir aquí.

Implementamos un CRUD para una entidad llamada Persona. Aquí les dejo la estructura de la BD.

El código incluye tres partes y de esa forma espero abordar este artículo, a saber: DAO, Servicio REST e Interfaz Gráfica de Usuario (GUI).

El DAO

Realmente aquí no hubo demasiada sofisticación, como el curso iba de Web 2.0, hicimos el menor énfasis en acceso a datos. Les dejo el pequeño DAO que hicimos para trabajar con la BD.

La interfaz, pensando en el uso futuro de IoC, la pueden conseguir aquí.

La clase concreta, aquí.

Si se fijan, la interfaz la implementamos siguiendo el estándar de nombrado de C# que me parece más fácil de seguir, es decir, agregamos una "I" al inicio de la interfaz. El resto es la implementación de la clase concreta. En caso de utilizar IoC, por ejemplo con Spring, la inicialización y destrucción de la conexión en el constructor y método finalize debería desaparecer. De hecho, como está ahora no me gusta mucho, pero lo hice de esta forma para mantener el código lo más simple posible.

La clase Persona es simplemente un POJO con todos los campos de la entidad: id, nombre y apellido. El código aquí.

El Servicio REST

El servicio REST lo implementamos con Jersey, que facilita bastante el código.

Para configurar Jersey se debe agregar como filtro en el Descriptor de Despliegue (web.xml), por supuesto después de haber descargado los JAR (en el proyecto dentro de WEB-INF/lib). Clic aquí para ver el web.xml.

Una vez configurado Jersey, implementamos la API, el código aquí. Cosas importantes que destacar:
  • Los métodos de consulta (GET) producen JSON.
  • Los métodos de modificación (PUT, POST y DELETE) producen HTML, success y error.
  • El método POST está implementado para hacer POST y DELETE por restricciones impuestas por la librería Prototype (ver aquí), para peticiones diferentes de GET y POST; ésta hace peticiones POST especificando el método en la petición a través del parámetro _method. Se puede modificar la librería para no hacer esto, pero me parece más robusto y escalable hacerlo del lado del servicio REST.
  • Para que pudiesen "convivir" Prototype y jQuery se tuvo que activar el modo de no conflictos de jQuery, ver aquí.

La API se puede probar utilizando cURL. A continuación los comandos de prueba que utilizamos, que además ayudan a describir el funcionamiento de los servicios:
$ echo "GET todos"; curl -X GET -H "Content-type:text/json" -v http://localhost:8080/TiendaVirtual/rest/persona
$ echo "GET uno"; curl -X GET -H "Content-type:text/json" -v http://localhost:8080/TiendaVirtual/rest/persona/1
$ echo "PUT"; curl -X PUT -H "Content-type:application/x-www-form-urlencoded" -d "nombre=Cambiar" -d 
"apellido=Apellido" -v http://localhost:8080/TiendaVirtual/rest/persona
$ echo "POST"; curl -X POST -H "Content-type:application/x-www-form-urlencoded" -d "id=1" -d "nombre=Cambiar" -d "apellido=Apellido" -v http://localhost:8080/TiendaVirtual/rest/persona
$ echo "DELETE"; curl -X DELETE -H "Content-type:application/x-www-form-urlencoded" -d "id=1" -v http://localhost:8080/TiendaVirtual/rest/persona

La GUI

La GUI la hicimos en HTML puro y utiliza una librería JS que separa las llamadas Ajax de la lógica de presentación.

El HTML lo pueden conseguir aqúi y la librería de utilidades (donde se manejan los eventos Ajax, con Prototype y jQuery) aquí. Cosas importantes que destacar:
  • Las llamadas de listar son síncronas, por lo que su manejo es diferente al del resto.
  • Las llamadas de modificación (agregar, modificar, eliminar) son asíncronas y funcionan con callback sobre listar.
  • Debido a que el código es de en un ejemplo para un curso, donde Javascript era uno de los temas, el listado se genera con DOM también (lamentablemente sólo funciona en Firefox, o al menos con Gecko como motor). Está deshabilitado por defecto, pero se puede activar con la variable TRABAJAR_DOM

Finalmente para ejecutar: http://localhost:8080/TiendaVirtual/persona.html

Espero este artículo sea de utilidad, sobre todo por el uso de Jersey y la invocación de la API vía Ajax. No conseguí demasiada información precisa y ejemplos que funcionaran desde el inicio. Inicialmente me apoyé bastante en el blog de Lars Vogel, aquí el ejemplo.


2 comentarios:

  1. Muy buen articulo Rodo, interesante la libreria Jersey, y a pesar de ser
    una solucion academica, pareciera robusta. Lo que me llama la atencion, particularmente en este momento en el que me encuentro trabajando con Ruby On Rails, es que todo lo que describes:

    1) ya viene integrado en un solo marco de trabajo RoR (a excepcion de Jersey)
    2) No estoy seguro cuanto le puede tomar hacer esto a un experto Java, pero estoy seguro que a un experto rails le tomaria la mitad del tiempo
    3) muchas tareas repetitivas y de buenas practicas: DAO, separacion en capas, etc; vienen integradas tambien.


    En conclusion: seria interesante probar este ejercicio academico en varias plataformas realizar comparaciones en factores tanto tecnicos(robustes, rendimiento, escalabilidad) como humanos y de gestion (productividad, monotonia, curva de aprendizaje)


    Saludos

    ResponderEliminar
  2. Tienes toda la razón del mundo. De hecho, el curso iba de web2.0 y no de las tecnologías específicas detrás del servidor. Hicimos los ejemplos con Java porque era el lenguaje con el que trabajaban los participantes generalmente. Luego, yo estaba rogando porque seleccionaran PHP :D

    Seguro que el desarrollo con PHP hubiese sido al menos 60% más rápido, luego, de la escalabilidad y otras cosas un poco más complejas, con seguridad no podría decir los mismo.

    ResponderEliminar