Story Transcript
Tema 3.6: El Estilo Arquitectónico REST
Índice
Introducción Conceptos básicos de REST
Recursos y Representaciones Conjunto fijo de operaciones Hypermedia: Cambio de estado Servicios auto-descriptivos Intermediarios y caches
Ejemplo: Movies RPC vs Movies REST Estilo REST vs Estilo RPC Valoración y Conclusiones
Introducción
REpresentational State Transfer. Estilo arquitectónico propuesto por Roy Fielding en 2000. La Web es, sin duda, la aplicación distribuida más exitosa de la historia. REST: Estilo arquitectónico para construir aplicaciones distribuidas inspirado en las características de la web. REST se basa fuertemente en HTTP 1.1:
Realmente es independiente de HTTP Pero HTTP 1.1 es el único protocolo utilizado masivamente diseñado para soportar los principios REST.
Introducción (y 2)
El estilo REST pretende que sea posible construir sistemas distribuidos compuestos por miles de servicios desarrollados y evolucionados independientemente, escalando a niveles comparables a la Web. Para ello hace énfasis en minimizar el acoplamiento entre servicios. A menudo se les denomina servicios web “RESTful”. Nosotros también los denominaremos servicios web REST “puros”.
Recursos y Representaciones (1)
Una aplicación REST se compone de recursos. Cada recurso es identificado mediante un identificador único (típicamente URLs):
http://www.boeing.com/aircraft/747 Puede representar un 747 de la compañía Boeing http://www.movieprovider.com/movies/Amelie Amelie en la BD de películas de movieprovider.com. http://www.amazon.com/Ajax-REST-Recipes-Problem-SolutionApproach/dp/1590597346/ El libro “Ajax and REST Recipes: A Problem-Solution Approach” (ISBN: 1590597346) en Amazon. http://en.wikipedia.org/wiki/HTTP Representa la información sobre HTTP proporcionada por Wikipedia.
Los identificadores (URLs) son globales.
Todo recurso tiene un nombre único a nivel mundial. No existen espacios de nombres restringidos a un servicio/aplicación. Eso no quiere decir que todos los recursos sean accesibles para todos (mecanismos de autorización).
Recursos y Representaciones (y2)
Al invocar la URL, el cliente obtiene una representación del recurso. La representación de un recurso puede variar en el tiempo.
El identificador está ligado al recurso, no a la representación. Si cambian los datos sobre HTTP en la Wikipedia, cambiará la representación. La URL apuntará siempre a la representación actual del recurso (entrada actual en Wikipedia).
La representación puede permitir actuar sobre el recurso. Ejemplo: Formularios para introducir datos. La representación puede contener nuevas URLs hacia otros recursos.
Ejemplo: cuando atravesamos un hiperenlace (URL) en la web estamos accediendo a un recurso cuya representación (página web) puede contener otros hiperenlaces.
Conjunto fijo de operaciones(1)
Interfaz uniforme. Las operaciones disponibles sobre los recursos son siempre las mismas y su semántica es conocida por todos los clientes y servicios. El estilo REST no dice cuáles deben ser esas operaciones, sólo que deben ser siempre las mismas y ser usadas consistentemente por los servicios. En el caso de HTTP: GET, POST, PUT, DELETE.
GET: Acceso a recursos y consultas. Sin efectos secundarios. PUT: Crear o reemplazar completamente la representación de un recurso. Idempotente. DELETE: Borrar un recurso. Idempotente. POST: Acciones que pueden tener efectos secundarios (creación / modificación de recursos, coste) y pueden no ser idempotentes.
Conjunto fijo de operaciones(y2)
Analogía con QUERY / UPDATE / INSERT /DELETE en una Base de datos.
PUT sirve para UPDATEs idempotentes e INSERTS (cliente decide el identificador). POST sirve para INSERT si servidor decide URL. Sirve para UPDATES no idempotentes. También se usa a menudo para UPDATES parciales.
Un servicio web REST debe utilizar sólo estas operaciones para manipular los recursos.
Esto quiere decir que cierta semántica de una invocación (“lo que hace”) sobre un recurso es conocida sin saber nada sobre el servicio.
Facilita la interoperabilidad entre aplicaciones. Para manipular un recurso de otra aplicación sólo se precisa su URL. Este conocimiento semántico limitado es suficiente para permitir capas intermedias (e.g. cache) transparentes que proporcionan servicios útiles.
Hypermedia: Cambio de Estado
La representación recibida por el cliente cambia (transfer) su estado (state). Una aplicación REST (web) puede verse como el grafo de transición de estados de un autómata.
Las representaciones de recursos (páginas) son estados del autómata. Las URLs (hiperenlaces) son transiciones entre estados. El estado en el que estamos determina qué otros estados (recursos) tenemos accesibles.
No hay estado específico para cada cliente en el servidor:
Cada petición del cliente debe incluir todo lo necesario para que el servidor pueda responderla. Facilita escalabilidad y replicación.
Servicios Autodescriptivos (1)
Idealmente, un cliente de un servicio REST necesitaría conocer a priori una única URL (la de entrada al servicio). El resto de sus interacciones serían guiadas por las representaciones por las que va navegando:
Hiperenlaces para operar sobre otros recursos. Plantillas de consulta/actualización que permitan operar sobre otros recursos usando parámetros especificados por el cliente:
Equivalente a formularios en la web. Permite que el servicio varíe los parámetros de la operación o la URL sobre la que actúan dinámicamente.
Servicios Autodescriptivos (2)
Las representaciones devueltas deben intentar expresarse en formatos conocidos a priori por todos los clientes posibles del servicio:
Intentar evitar formatos propietarios de cada servicio. En lo posible, utilizar tipos MIME con semántica conocida (e.g. ATOM). Si los clientes posibles están dentro de una organización intentar usar estándares de la organización. Si hay que añadir información específica, intentar proporcionar también una representación en un formato estándar (e.g. ATOM) Así, cualquier cliente podrá al menos obtener parte de la información.
Servicios Autodescriptivos (y 3)
Si esto se consigue, el cliente y el servicio están muy desacoplados:
El servicio puede cambiar totalmente su funcionamiento interno (e.g. esquemas de URL, campos consultables para un recurso) sin que el cliente rompa. Análogo a un usuario humano que accede con su browser a una web que ha cambiado totalmente -> aún eres capaz de usar el servicio.
En muchos casos, puede ser muy difícil / imposible de conseguir totalmente:
¿Cómo expresar forms entendibles por programas?. Existen varias propuestas, aún no muy usadas (e.g. Xforms). No hay vocabularios estándar para todo !
Intentar ajustarse lo más posible o adoptar soluciones parciales (e.g. tener una representación en ATOM además de la representación en un formato específico)
Intermediarios y Caches (1)
Soporte para Cache:
Las representaciones deben poderse marcar como cacheables o no por capas intermedias. Soporte para tiempos de expiración, detección de si hay o no nuevas versiones de un recurso,…
El uso de una interfaz uniforme permite introducir intermediarios de forma transparente entre los clientes y los recursos:
Servicios de eficiencia, seguridad,… Ejemplos : Proxies . Pueden implementar reintentos de forma transparente con peticiones idempotentes. Servidores de cache. Sabe que las peticiones GET de un recurso invalidan su copia, las otras sí. Filtros de contenido. Pueden decidir actuar sólo sobre peticiones GET.
Intermediarios y Caches (2)
La interfaz uniforme permite que los clientes también pueden realizar ciertos procesamientos sobre los recursos de un servicio sin conocimiento a priori:
E.g. un crawler sabe que puede hacer GETS de representaciones.
En un enfoque RPC típico, la semántica de una operación no es conocida para el intermediario/cliente a menos que se le configure específicamente para cada servicio. Si además de respetar la interfaz uniforme, se consigue que el sistema sea auto-descriptivo en un grado alto, los clientes / intermediarios pueden realizar operaciones más sofisticadas.
Intermediarios y Caches (y 3)
Intermediarios:
Servicio-1 Cache HTTP
Cliente
HTTP HTTP Servicio-2
HTTP
... Servicio-N
Ejemplo: Movies RPC (1)
Ejemplo películas al estilo RPC (CORBA, DCOM, SOAP,…) Proveedor proporciona una interfaz que consiste en, entre otras, las siguientes operaciones: MovieSummary [] findMovies() MovieSummary [] findMoviesByDate(Calendar date) MovieInformationDetail getMovieInformation (String movieId) String addMovie(MovieInformationDetail info) void updateMovie (String movieId,MovieInformationDetail info) void removeMovie (String movieId) void addGross (double amount, movieId, Calendar week)
NOTA: usamos notación “a la JAVA”.
Ejemplo: Movies RPC (2)
Los clientes del proveedor suelen utilizar:
findMovies permite obtener la lista de todas las películas. findMoviesByDate permite obtener la cartelera de un día determinado. Ambos métodos devuelven la información más importante de una película (objeto MovieSummary):
Se incluye un identificador numérico para cada película. No se devuelve toda la información porque puede ser bastante grande y normalmente no se necesita toda.
Si se quiere toda la información de una película puede llamarse a getMovieInformation pasándole el identificador de la película.
Ejemplo: Movies RPC (y 3)
Las aplicaciones que editan los contenidos del proveedor (internas o externas) suelen utilizar
addMovie permite añadir una película. removeMovie permite eliminar una película. updateMovie. Permite reemplazar la información completa de una película. addGross. Permite especificar la recaudación semanal de una película. Modifica el atributo recaudación total de la misma sumándole la nueva recaudación. No es idempotente.
Las operaciones pueden lanzar exceptions ad-hoc como las que vimos en temas anteriores.
Ejemplo: Movies REST (1)
Cada película es un recurso con una URL asociada:
http://www.moviesprovider.com/movies/Amelie http://www.moviesprovider.com/movies/The_Godfather_Part_II
Su representación es un documento XML.
Similar al ejemplo utilizado en el tema 2 con elementos de datos adicionales (e.g. recaudación, productora, puntero al trailer, punteros a biografías de los actores, …). Podría utilizarse una representación alternativa en ATOM (del estilo de la que vimos en el Tema 3.2) para los clientes que no entiendan nuestro formato:
A través de cabeceras HTTP es posible para el cliente especificar qué formatos acepta.
Podría no utilizarse XML:
Si los datos son sencillos. Ejemplo: CSV. Si al cliente puede facilitarle su procesamiento. Ejemplo: desde clientes Javascript, es más fácil usar JSON.
Ejemplo: Movies REST (2)
http://www.moviesprovider.com/movies es un recurso colección que contiene:
Su representación es un documento XML:
La información resumida de todas las películas. Una referencia al recurso de cada película. Un “formulario” que indica como buscar por fecha. Incluye alguna información de resumen de cada película. Usa Xlink (http://www.w3.org/TR/xlink/) para especificar referencias a otros recursos. Usa una URI Template (http://bitworking.org/projects/URITemplates/spec/draft-gregorio-uritemplate-03.html) para especificar como consultar la colección por fecha. Podría haber una representación alternativa en ATOM para los clientes que no entendiesen nuestro formato (no serviría para la interfaz de consulta).
Análogo a una página web convencional.
Ejemplo: Movies REST (3)