La transferencia de estado representacional (en inglés representational state transfer) o REST es un estilo de arquitectura software para sistemas hipermedia distribuidos como la World Wide Web. El término se originó en el año 2000, en una tesis doctoral sobre la web escrita por Roy Fielding, uno de los principales autores de la especificación del protocolo HTTP y ha pasado a ser ampliamente utilizado por la comunidad de desarrollo.

Historia La Web empezó a ser de uso diario en 1993-4, cuando empezaron a estar disponibles sitios web para uso general. En ese momento, solo había una descripción fragmentada de la arquitectura web y había presión en la industria para acordar algún estándar para los protocolos de interfaz web. Por ejemplo, se habían agregado varias extensiones experimentales al protocolo de comunicación (HTTP) para admitir proxies y se estaban proponiendo más extensiones, pero existía la necesidad de una arquitectura web formal con la que evaluar el impacto de estos cambios.

Juntos, los grupos de trabajo del W3C y del IETF comenzaron a trabajar en la creación de descripciones formales de los tres estándares principales de la web: URI, HTTP y HTML. Roy Fielding estuvo involucrado en la creación de estos estándares (específicamente HTTP 1.0 y 1.1, y URI), y durante los siguientes seis años desarrolló el estilo arquitectónico REST, probando sus restricciones en los estándares de protocolo de la web y usándolo como un medio para definir mejoras arquitectónicas y para identificar desajustes arquitectónicos. Fielding definió REST en su disertación de doctorado de 2000 "Estilos arquitectónicos y el diseño de arquitecturas de software basadas en redes" en UC Irvine.

Descripción

Si bien el término REST se refería originalmente a un conjunto de principios de arquitectura —descritos más abajo—, en la actualidad se usa en el sentido más amplio para describir cualquier interfaz entre sistemas que utilice directamente HTTP para obtener datos o indicar la ejecución de operaciones sobre los datos, en cualquier formato (XML, JSON, etc) sin las abstracciones adicionales de los protocolos basados en patrones de intercambio de mensajes, como por ejemplo SOAP. Es posible diseñar sistemas de servicios web de acuerdo con el estilo arquitectural REST de Fielding y también es posible diseñar interfaces XMLHTTP de acuerdo con el estilo de llamada a procedimiento remoto (RPC), pero sin usar SOAP. Estos dos usos diferentes del término REST causan cierta confusión en las discusiones técnicas, aunque RPC no es un ejemplo de REST.

REST afirma que la web ha disfrutado de escalabilidad como resultado de una serie de diseños fundamentales clave:

Un protocolo cliente/servidor sin estado: cada mensaje HTTP contiene toda la información necesaria para comprender la petición. Como resultado, ni el cliente ni el servidor necesitan recordar ningún estado de las comunicaciones entre mensajes. Sin embargo, en la práctica, muchas aplicaciones basadas en HTTP utilizan cookies y otros mecanismos para mantener el estado de la sesión (algunas de estas prácticas, como la reescritura de URLs, no son permitidas por REST)

Un conjunto de operaciones bien definidas que se aplican a todos los recursos de información: HTTP en sí define un conjunto pequeño de operaciones, las más importantes son POST, GET, PUT y DELETE. Con frecuencia estas operaciones se equiparan a las operaciones CRUD en bases de datos (CLAB en castellano: crear, leer, actualizar, borrar) que se requieren para la persistencia de datos, aunque POST no encaja exactamente en este esquema.

Una sintaxis universal para identificar los recursos. En un sistema REST, cada recurso es direccionable únicamente a través de su URI.

El uso de hipermedios, tanto para la información de la aplicación como para las transiciones de estado de la aplicación: la representación de este estado en un sistema REST son típicamente HTML o XML. Como resultado de esto, es posible navegar de un recurso REST a muchos otros, simplemente siguiendo enlaces sin requerir el uso de registros u otra infraestructura adicional.

Recursos

Un concepto importante en REST es la existencia de recursos (elementos de información), que pueden ser accedidos utilizando un identificador global (un Identificador Uniforme de Recurso). Para manipular estos recursos, los componentes de la red (clientes y servidores) se comunican a través de una interfaz estándar (HTTP) e intercambian representaciones de estos recursos (los ficheros que se descargan y se envían) - es cuestión de debate, no obstante, si la distinción entre recursos y sus representaciones es demasiado platónica para su uso práctico en la red, aunque es popular en la comunidad RDF.

La petición puede ser transmitida por cualquier número de conectores (por ejemplo clientes, servidores, cachés, túneles, etc.) pero cada uno lo hace sin "ver más allá" de su propia petición (lo que se conoce como stateless (sin estado), otra restricción de REST, que es un principio común con muchas otras partes de la arquitectura de redes y de la información). Así, una aplicación puede interactuar con un recurso conociendo el identificador del recurso y la acción requerida, no necesitando conocer si existen cachés, proxys, cortafuegos, túneles o cualquier otra cosa entre ella y el servidor que guarda la información. La aplicación, sin embargo, debe comprender el formato de la información devuelta (la representación), que es por lo general un documento HTML o XML, aunque también puede ser una imagen o cualquier otro contenido.

REST frente a RPC

Una aplicación web REST requiere un enfoque de diseño diferente a una aplicación basada en RPC (llamada de procedimiento remoto). En RPC, se pone el énfasis en la diversidad de operaciones del protocolo, o verbos; por ejemplo una aplicación RPC podría definir operaciones como:

getUser() addUser() removeUser() updateUser() getLocation() addLocation() removeLocation() updateLocation() listUsers() listLocations() findLocation() findUser()

En REST, al contrario, el énfasis se pone en los recursos, o sustantivos; especialmente en los nombres que se le asigna a cada tipo de recurso. Por ejemplo, una aplicación REST podría definir algunos tipos de recursos asignándoles estos nombres:

Usuario {} Localización {}

Cada recurso tendría su propio identificador, como http://www.example.org/locations/us/ny/new_york_city. Los clientes trabajarían con estos recursos a través de las operaciones estándar de HTTP, como GET para descargar una copia del recurso. Obsérvese cómo cada objeto tiene su propia URL y puede ser fácilmente cacheado, copiado y guardado como marcador. POST se utiliza por lo general para acciones con efectos laterales, como enviar una orden de compra o añadir ciertos datos a una colección.

Por ejemplo, el registro para un usuario podría tener el siguiente aspecto:

<usuario> <nombre>Maximiliano Alejandro</nombre> <sexo>hombre</sexo> <localización href="http://www.example.org/locations/us/ny/new_york_city">Nueva York, NY, US</localización> </usuario>

Para actualizar la localización del usuario, un cliente REST podría primero descargar el registro XML anterior usando GET. El cliente después modificaría el fichero para cambiar la localización y lo subiría al servidor utilizando HTTP PUT.

Nótese, sin embargo, que los verbos HTTP (POST, GET, PUT, DELETE) no proporcionan ningún mecanismo estándar para descubrir recursos -- no hay ninguna operación LIST o FIND en HTTP, que se corresponderían con las operaciones list*() y find*() en el ejemplo RPC. En su lugar, las aplicaciones basadas en datos REST resuelven el problema tratando una colección de resultados de búsqueda como otro tipo de recurso, lo que requiere que los diseñadores de la aplicación conozcan URLs adicionales para mostrar o buscar cada tipo de recurso.

Por ejemplo, una petición GET HTTP sobre la URL http://www.example.org/locations/us/ny/ podría devolver un enlace a una lista de ficheros en XML con todas las localizaciones posibles en Nueva York, mientras que una petición GET a la URL http://www.example.org/users?surname=Michaels podría devolver una lista de enlaces a todos los usuarios con el apellido "Michaels".

REST proporciona algunas indicaciones sobre cómo realizar este tipo de acciones como parte de su restricción "hipermedia como el medio de estado de la aplicación", lo que sugiere el uso de un lenguaje de formularios (tales como un formulario HTML) para especificar consultas parametrizadas.

La iniciativa OpenSearch de A9.com intenta estandarizar las búsquedas usando REST estableciendo especificaciones para descubrir recursos y un formato genérico para utilizar con sistemas basados en REST, incluyendo el RDF, XTM, Atom, RSS (en sus varias formas) y XML con XLink para gestionar los enlaces.

Principios

En su disertación original del año 2000, Roy T. Fielding define REST como un "...estilo arquitectónico para sistemas distribuidos de hipermedia, describiendo los principios de ingeniería de software que guían REST y las constantes de interacción elegidas para retener esos principios...". Estos principios son:

Arquitectura cliente-servidor. Hace hincapié en la separación de responsabilidades y la portabilidad. Cuanto menos conoce el servidor sobre el cliente más desacoplada está su interacción y más fácil resulta el cambio de componentes. Por definición, REST es una arquitectura diseñada para funcionar con sistemas distribuidos centralizados, en oposición a los que no usan un servidor como nodo principal –por ejemplo, mediante una arquitectura entre iguales o P2P–. Ausencia de estado. El estado se guarda y mantiene en el cliente y no en el servidor. Es decir, las solicitudes deben proveer toda la información necesaria para poder realizarse en un servidor que no mantiene estados, por lo que no guarda contexto entre llamadas para un mismo cliente. Esto no significa que el servidor no pueda cambiar de contexto y facilitar esa transición al cliente. Para conseguir esto normalmente se usan redirecciones de peticiones; de forma que el cliente solo realice una petición y el servidor la procese en un endpoint o recurso, y la redirija a otro para continuar su procesamiento allí. Esto ocurre de forma transparente para el cliente, y es habitual por ejemplo en casos de uso relacionados con el registro y posterior inicio de sesión automático: El servidor crea la cuenta, genera un token de sesión y, en vez de devolverlo al cliente para que este llame a la URI de login –lo que aumentaría los tiempos, pues cada petición es costosa para los clientes–, lo reenvía a dicho endpoint de inicio de sesión él mismo, devolviendo al cliente la respuesta final de la última petición realizada. Habilitación y uso de la caché. Todas las solicitudes deben declarar si son o no cacheables, una forma estándar de hacerlo es con los encabezados cache-control de HTTP. De esta forma, se pueden enviar respuestas cacheadas desde cualquier punto de la red sin necesidad de que la petición llegue al servidor. Pese a que en el caso de una API dinámica esto puede parecer no tener sentido, puede ahorrar costes en casos de datos inmutables, como definiciones. Sistema por capas. Tiene relación con la separación de responsabilidades anteriormente mencionada, y establece que un cliente debe conocer únicamente la capa a la que le está hablando. Es decir, no debe tener en cuenta aspectos concretos, como particularidades de la base de datos usada; o abstracciones como cachés, proxies o balanceadores de carga implicados. Si se necesita seguridad, esta se debe añadir encima de los servicios Web, permitiendo que la lógica y seguridad permanezcan separadas. Interfaz uniforme.