CAPÍTULO 5 Transferencia de estado representacional (REST) Este capítulo presenta y elabora el estilo arquitectónico Representational State Transfer (REST) para sistemas hipermedia distribuidos, describiendo los principios de ingeniería de software que guían a REST y las restricciones de interacción elegidas para retener esos principios, al tiempo que los contrasta con las restricciones de otros estilos arquitectónicos. REST es un estilo híbrido derivado de varios de los estilos arquitectónicos basados en red descritos en el Capítulo 3 y combinado con restricciones adicionales que definen una interfaz de conector uniforme. El marco de la arquitectura de software del Capítulo 1 se utiliza para definir los elementos arquitectónicos de REST y examinar muestras de procesos, conectores y vistas de datos de arquitecturas prototípicas. 5.1 Derivando RESTO La lógica de diseño detrás de la arquitectura web se puede describir mediante un estilo arquitectónico que consiste en el conjunto de restricciones aplicadas a los elementos dentro de la arquitectura. Al examinar el impacto de cada restricción a medida que se agrega al estilo en evolución, podemos identificar las propiedades inducidas por las restricciones de la Web. Luego se pueden aplicar restricciones adicionales para formar un nuevo estilo arquitectónico que refleje mejor las propiedades deseadas de una arquitectura web moderna. Esta sección proporciona una descripción general de REST recorriendo el proceso de obtención de un estilo arquitectónico. Las secciones posteriores describirán con más detalle las restricciones específicas que componen el estilo REST. 5.1.1 Comenzando con el estilo nulo Hay dos perspectivas comunes sobre el proceso de diseño arquitectónico, ya sea para edificios o para software. La primera es que un diseñador comienza con nada (una pizarra en blanco, una pizarra o un tablero de dibujo) y construye una arquitectura a partir de componentes familiares hasta que satisface las necesidades del sistema previsto. La segunda es que un diseñador comienza con las necesidades del sistema como un todo, sin restricciones, y luego identifica y aplica restricciones de forma incremental a los elementos del sistema para diferenciar el espacio de diseño y permitir que las fuerzas que influyen en el comportamiento del sistema fluyan naturalmente, en armonía con el sistema. Donde el primero enfatiza la creatividad y la visión ilimitada, el segundo enfatiza la moderación y la comprensión del contexto del sistema. REST se ha desarrollado utilizando este último proceso. El estilo Nulo ( Figura 5-1 ) es simplemente un conjunto vacío de restricciones. Desde una perspectiva arquitectónica, el estilo nulo describe un sistema en el que no existen límites definidos entre los componentes. Es el punto de partida para nuestra descripción de REST. 5.1.2 Cliente-Servidor Las primeras restricciones agregadas a nuestro estilo híbrido son las del estilo arquitectónico cliente-servidor ( Figura 5-2 ), descritas en la Sección 3.4.1 . La separación de preocupaciones es el principio detrás de las restricciones cliente-servidor. Al separar las preocupaciones de la interfaz de usuario de las preocupaciones de almacenamiento de datos, mejoramos la portabilidad de la interfaz de usuario a través de múltiples plataformas y mejoramos la escalabilidad al simplificar los componentes del servidor. Sin embargo, quizás lo más importante para la Web es que la separación permite que los componentes evolucionen de forma independiente, lo que respalda el requisito de escala de Internet de múltiples dominios organizacionales. 5.1.3 Apátrida A continuación, agregamos una restricción a la interacción cliente-servidor: la comunicación debe ser de naturaleza sin estado, como en el estilo cliente-servidor sin estado (CSS) de la Sección 3.4.3 ( Figura 5-3 ), de modo que cada solicitud del cliente a El servidor debe contener toda la información necesaria para comprender la solicitud y no puede aprovechar ningún contexto almacenado en el servidor. Por lo tanto, el estado de la sesión se mantiene completamente en el cliente. Esta restricción induce las propiedades de visibilidad, confiabilidad y escalabilidad. Se mejora la visibilidad porque un sistema de monitoreo no tiene que mirar más allá de un solo dato de solicitud para determinar la naturaleza completa de la solicitud. Se mejora la confiabilidad porque facilita la tarea de recuperarse de fallas parciales [ 133 ]. La escalabilidad se mejora porque no tener que almacenar el estado entre solicitudes permite que el componente del servidor libere recursos rápidamente y simplifica aún más la implementación porque el servidor no tiene que administrar el uso de recursos entre solicitudes. Como la mayoría de las elecciones arquitectónicas, la restricción sin estado refleja una compensación de diseño. La desventaja es que puede disminuir el rendimiento de la red al aumentar los datos repetitivos (sobrecarga por interacción) enviados en una serie de solicitudes, ya que esos datos no se pueden dejar en el servidor en un contexto compartido. Además, colocar el estado de la aplicación en el lado del cliente reduce el control del servidor sobre el comportamiento coherente de la aplicación, ya que la aplicación depende de la implementación correcta de la semántica en varias versiones del cliente. 5.1.4 Caché Para mejorar la eficiencia de la red, agregamos restricciones de caché para formar el estilo cliente-caché-servidor sin estado de la Sección 3.4.4 ( Figura 5-4 ). Las restricciones de caché requieren que los datos dentro de una respuesta a una solicitud se etiqueten implícita o explícitamente como almacenables en caché o no almacenables en caché. Si una respuesta se puede almacenar en caché, se otorga a la memoria caché del cliente el derecho de reutilizar los datos de respuesta para solicitudes posteriores equivalentes. La ventaja de agregar restricciones de caché es que tienen el potencial de eliminar parcial o completamente algunas interacciones, mejorando la eficiencia, la escalabilidad y el rendimiento percibido por el usuario al reducir la latencia promedio de una serie de interacciones. Sin embargo, la contrapartida es que un caché puede disminuir la confiabilidad si los datos obsoletos dentro del caché difieren significativamente de los datos que se habrían obtenido si la solicitud se hubiera enviado directamente al servidor. La arquitectura web temprana, como se muestra en el diagrama de la Figura 5-5 [ 11 ], se definía mediante el conjunto de restricciones cliente-caché-sin estado-servidor. Es decir, la lógica de diseño presentada para la arquitectura web antes de 1994 se centró en la interacción cliente-servidor sin estado para el intercambio de documentos estáticos a través de Internet. Los protocolos para comunicar interacciones tenían soporte rudimentario para cachés no compartidos, pero no restringían la interfaz a un conjunto consistente de semántica para todos los recursos. En su lugar, la Web se basó en el uso de una biblioteca de implementación cliente-servidor común (CERN libwww) para mantener la coherencia entre las aplicaciones Web. Los desarrolladores de implementaciones web ya habían superado el diseño inicial. Además de los documentos estáticos, las solicitudes podrían identificar servicios que generaron respuestas dinámicamente, como mapas de imágenes [Kevin Hughes] y scripts del lado del servidor [Rob McCool]. También se había comenzado a trabajar en componentes intermediarios, en forma de proxies [ 79 ] y cachés compartidos [ 59 ], pero se necesitaban extensiones a los protocolos para que se comunicaran de manera confiable. Las siguientes secciones describen las restricciones agregadas al estilo arquitectónico de la Web para guiar las extensiones que forman la arquitectura Web moderna. 5.1.5 Interfaz uniforme La característica central que distingue el estilo arquitectónico REST de otros estilos basados en red es su énfasis en una interfaz uniforme entre los componentes ( Figura 5-6). Al aplicar el principio de generalidad de la ingeniería de software a la interfaz del componente, se simplifica la arquitectura general del sistema y se mejora la visibilidad de las interacciones. Las implementaciones están desvinculadas de los servicios que brindan, lo que fomenta la capacidad de evolución independiente. Sin embargo, la contrapartida es que una interfaz uniforme degrada la eficiencia, ya que la información se transfiere en una forma estandarizada en lugar de una que sea específica para las necesidades de una aplicación. La interfaz REST está diseñada para ser eficiente para la transferencia de datos hipermedia de grano grande, optimizándose para el caso común de la Web, pero dando como resultado una interfaz que no es óptima para otras formas de interacción arquitectónica. Para obtener una interfaz uniforme, se necesitan múltiples restricciones arquitectónicas para guiar el comportamiento de los componentes. REST está definido por cuatro restricciones de interfaz: identificación de recursos; manipulación de recursos a través de representaciones; mensajes autodescriptivos; e hipermedia como motor de estado de la aplicación. Estas restricciones se discutirán en la Sección 5.2 . 5.1.6 Sistema en capas Para mejorar aún más el comportamiento de los requisitos a escala de Internet, agregamos restricciones de sistema en capas ( Figura 5-7 ). Como se describe en la Sección 3.4.2, el estilo de sistema en capas permite que una arquitectura se componga de capas jerárquicas al restringir el comportamiento de los componentes de modo que cada componente no pueda "ver" más allá de la capa inmediata con la que está interactuando. Al restringir el conocimiento del sistema a una sola capa, limitamos la complejidad general del sistema y promovemos la independencia del sustrato. Las capas se pueden usar para encapsular servicios heredados y para proteger nuevos servicios de clientes heredados, lo que simplifica los componentes al mover la funcionalidad que se usa con poca frecuencia a un intermediario compartido. Los intermediarios también se pueden utilizar para mejorar la escalabilidad del sistema al permitir el equilibrio de carga de los servicios en varias redes y procesadores. La principal desventaja de los sistemas en capas es que agregan sobrecarga y latencia al procesamiento de datos, lo que reduce el rendimiento percibido por el usuario [ 32 ]. Para un sistema basado en red que admita restricciones de caché, esto puede compensarse con los beneficios del almacenamiento en caché compartido en los intermediarios. La ubicación de cachés compartidos en los límites de un dominio organizacional puede generar importantes beneficios de rendimiento [ 136 ]. Estas capas también permiten aplicar políticas de seguridad en los datos que cruzan los límites de la organización, tal como lo exigen los cortafuegos [ 79 ]. La combinación del sistema en capas y las restricciones de interfaz uniforme inducen propiedades arquitectónicas similares a las del estilo uniforme de tubería y filtro ( Sección 3.2.2 ). Aunque la interacción REST es bidireccional, los flujos de datos de grano grande de la interacción hipermedia pueden procesarse como una red de flujo de datos, con componentes de filtro aplicados selectivamente al flujo de datos para transformar el contenido a medida que pasa [26 ] . Dentro de REST, los componentes intermediarios pueden transformar activamente el contenido de los mensajes porque los mensajes son autodescriptivos y su semántica es visible para los intermediarios. 5.1.7 Código bajo demanda La adición final a nuestro conjunto de restricciones para REST proviene del estilo de código bajo demanda de la Sección 3.5.3 ( Figura 5-8 ). REST permite ampliar la funcionalidad del cliente descargando y ejecutando código en forma de applets o scripts. Esto simplifica a los clientes al reducir la cantidad de funciones necesarias para implementar previamente. Permitir que las funciones se descarguen después de la implementación mejora la extensibilidad del sistema. Sin embargo, también reduce la visibilidad y, por lo tanto, es solo una restricción opcional dentro de REST. La noción de una restricción opcional puede parecer un oxímoron. Sin embargo, tiene un propósito en el diseño arquitectónico de un sistema que abarca múltiples límites organizativos. Significa que la arquitectura solo obtiene el beneficio (y sufre las desventajas) de las restricciones opcionales cuando se sabe que están vigentes para algún ámbito del sistema general. Por ejemplo, si se sabe que todo el software de cliente dentro de una organización admite applets de Java [ 45], entonces los servicios dentro de esa organización pueden construirse de manera que obtengan el beneficio de una funcionalidad mejorada a través de clases Java descargables. Al mismo tiempo, sin embargo, el cortafuegos de la organización puede impedir la transferencia de subprogramas de Java desde fuentes externas y, por lo tanto, para el resto de la Web parecerá que esos clientes no admiten código bajo demanda. Una restricción opcional nos permite diseñar una arquitectura que admita el comportamiento deseado en el caso general, pero con el entendimiento de que puede estar deshabilitado en algunos contextos. 5.1.8 Resumen de derivación de estilo REST consiste en un conjunto de restricciones arquitectónicas elegidas por las propiedades que inducen en las arquitecturas candidatas. Aunque cada una de estas restricciones puede considerarse de forma aislada, describirlas en términos de su derivación de estilos arquitectónicos comunes facilita la comprensión de la lógica detrás de su selección. La Figura 5-9 muestra gráficamente la derivación de las restricciones de REST en términos de los estilos arquitectónicos basados en redes examinados en el Capítulo 3.