Servicios Web Basados en REST

¿Has checado tu facebook recientemente? ¿Escribiste en 140 caractéres vía twitter lo que hiciste hoy? ¿Estás suscrito a un canal RSS de algún blog interesante? ¿Envías bookmarks a del.icio.us? Si respondiste que sí a por lo menos una de estas preguntas, entonces este artículo te interesa. Parte del éxito de estos servicios en la web, es la arquitectura sobre la que fueron desarrollados. Dicho estilo arquitectónico es conocido como REST y en este artículo conoceremos un poco al respecto.¿Qué es REST?
El término REST (Representational State Transfer) se refiere a un estilo arquitectónico propuesto en el año 2000 por Roy Fielding. Conforme han pasado los años, REST ha cobrado gran popularidad, y se ha convertido en la recomendación de facto para diseñar arquitecturas de aplicaciones web modernas.

Vale la pena aclarar que REST no es un estándar. No existe una especificación formal de REST, y tampoco encontrarás un kit de desarrollo para REST. Simplemente es un estilo arquitectónico, y por lo tanto no se puede embotellar. Simplemente hay que entenderlo para poder diseñar aplicaciones que cumplan el estilo REST.

De acuerdo con Fielding: “Representational State Transfer pretende evocar una imagen de cómo se comporta una aplicación web bien diseñada: es una red de páginas web (una máquina virtual de estados), donde el usuario navega a través de la aplicación al ir seleccionando hiperligas (transiciones de estados), que resultan en una nueva página (el nuevo estado de la aplicación) siendo transferida y
desplegada al usuario.”

Habiendo explicado la filosofía detrás de REST, procedamos a conocer los fundamentos de los servicios web basados en REST. Un RESTful web service, o servicio web basado en REST típicamente sigue cuatro principios de diseño:
1. Utiliza los métodos HTTP de manera explícita
2. No mantiene estados
3. Expone URIs en forma de directorios
4. Transfiere datos por medio de XML y/o JSON

Veamos a que se refiere cada uno de estos principios.

Utiliza los métodos HTTP de manera explícita
En REST las operaciones disponibles sobre los recursos son siempre las mismas y su semántica es conocida por todos los clientes y servicios. Empatando esto con los tipos de solicitud de HTTP
tenemos que:
• POST: Crea un recurso
• GET: Obtiene un recurso
• PUT: Cambia el estado de un recurso
• DELETE: Elimina un recurso

Es común encontrar aplicaciones que utilizan el método GET para agregar o modificar datos, lo cual no va de acuerdo con lo que REST recomienda. Veamos el siguiente ejemplo de una petición GET:

GET /agregarusuario?nombre=Nao HTTP/1.1

Si la petición se procesa con éxito, un nuevo usuario sería agregado a la base de datos. Aquí el primer problema es semántico, pues los servidores web están diseñados para responder a las peticiones
HTTP GET con la búsqueda de recursos que concuerden con la ruta del URI y devolver esta representación en respuesta, mas no añadir un registro a la base de datos. Desde el punto de vista del
protocolo y del servidor web compatible con HTTP/1.1, este uso del GET es inconsistente. El otro problema, y mucho más grave, es que al ejecutar eliminaciones, modificaciones o creación de registros
en la base de datos de esta forma, se puede provocar que las herramientas de caché web y los motores de búsqueda realicen cambios no intencionales en el servidor.

Para evitar estos problemas se utiliza una petición REST, que consiste en cambiar los nombres y valores de los parámetros en la petición del URI a tags XML. Los tags resultantes, son enviados
en el cuerpo de un HTTP POST cuyo URI de petición es el padre de la entidad. Entonces, una petición correcta quedaría de la siguiente forma:

POST /usuarios HTTP/1.1
Host: www.example.com
Content-type: application/xml

Nao


De esta forma existe un uso correcto de HTTP POST y la inclusión de los datos en el cuerpo de la petición. Recordemos que GET se usa solamente para recuperar datos y es una operación que no debe
poder alterar datos.

No mantiene estados
En un servicio web REST, el cliente envía peticiones que incluyen todos los datos necesarios para cumplir el pedido, de manera que los componentes en los servidores intermedios puedan gestionar
la carga sin mantener localmente el estado entre las peticiones. El servidor es el responsable de generar las respuestas y proveer una interfaz que le permita al cliente mantener el estado de la aplicación. De esta forma se mejora el rendimiento de los servicios web y se simplifica el diseño e implementación. Además se elimina la necesidad de sincronizar los datos de la sesión con una aplicación externa.

En la plataforma JEE, un entorno de servicios con estado necesita bastante análisis y diseño para poder almacenar los datos eficientemente y poder sincronizar la sesión del cliente dentro de un cluster de servidores. Aquí ocurre un problema que le resulta familiar a los desarrolladores de servlets/JSP y EJB,
quienes a menudo tienen que buscar la causa de una java. io.NotSerializableException cuando ocurre la replicación de una sesión. Puede ocurrir tanto en el contenedor de Servlets al intentar replicar la HttpSession o en el contenedor de EJB al replicar uno con estado. Además, la sincronización seguro que impactará negativamente en el rendimiento del servidor.

Los servicios sin estado son mucho más simples de diseñar, escribir y distribuir a través de múltiples servidores. Un servicio sin estado no sólo funciona mejor, sino que además mueve la responsabilidad de mantener el estado al cliente de la aplicación.

Expone URIs en forma de directorios
Las URI deben ser intuitivas y funcionar como una interfaz auto-documentada que necesita de muy poca explicación para que un desarrollador pueda comprender a lo que apunta y cuales son los recursos
derivados relacionados. Una forma de lograr este nivel de usabilidad es definir URIs con una estructura al estilo de los directorios. Dicha estructura jerárquica cuenta una ruta raíz única, y va abriendo ramas
a través de las subrutas para exponer las áreas principales del servicio, lo que da como resultado un árbol con subordinados y padres organizados como nodos.

Ejemplo:
http://www.xyz.org/discusion/temas/{id-de-tema}

En este ejemplo, la raíz /discusion tiene un nodo /temas como hijo, y bajo este hay un conjunto de temas (tecnología, actualidad, etc.), cada uno de los cuales apunta a un hilo de discusión. Dentro de
esta estructura resulta fácil recuperar hilos de discusión al escribir algo después de /temas/. Una gran ventaja es que estaremos ocultando la tecnología usada en el servidor que aparecería como extensión de archivos (.jsp, .php, .asp), de manera que en un futuro podemos mudar la solución a otra tecnología sin cambiar las URI, permitiendo que el cliente pueda generar bookmarks que permanezcan válidos.

Este es el nivel de simplicidad que buscamos con REST. Tanto humanos como máquinas pueden generar estas estructuras de URI porque están basadas en reglas.

Estos son algunos lineamientos comunes para crear URIs para servicios web REST:
• Mantener todo en minúsculas.
• Sustituir los espacios con guiones o guiones bajos (uno u otro).
• Evitar el uso de strings de consulta.

Transfiere XML, JSON, o ambos
La representación de un recurso refleja el estado actual del mismo y sus atributos al momento en que el cliente de la aplicación realiza la petición. Esto podría ser una representación de un registro de la base de datos que consiste en la asociación entre columnas y tags XML, donde los valores de los elementos en el XML contienen los valores de las filas.

Un ejemplo de una representación de un recurso conectado podría ser un tema de discusión raíz con todos sus atributos e hiperligas embebidos a las respuestas al tema.


{comentario}

{tema}/gaz”/>




Es bueno construir los servicios de manera que usen el atributo HTTP Accept del encabezado, en donde el valor de este campo es un tipo MIME, mecanismo conocido como negociación de contenido. Esto permite que el servicio sea utilizado por distintos clientes escritos en diferentes lenguajes, corriendo en diversas plataformas y dispositivos. Así los clientes pueden elegir cómo manejar distintos tipos de documentos, y se minimiza el acoplamiento de datos entre el servicio y las aplicaciones que lo consumen.

Referencias
[1]. Roy Thomas Fielding. Architectural Styles and the Design of Net work-based Software Architectures. http://bit.ly/14V9rQ
[2]. RESTful Web Services. http://bit.ly/3itQu
[3]. Roger L. Costello. Building Web Services the REST Way.http:// bit.ly/1wVQPx