Servicios Web de RESTful

REST define un conjunto de principios arquitectónicos por los que se pueden diseñar servicios Web que se centran en los recursos de un sistema, lo que incluye la forma en que los estados de los recursos se dirigen y transfieren a través de HTTP por un amplio rango de clientes que están escritos en diferentes lenguajes. Si lo medimos por el número de servicios Web que lo emplean, en los últimos años REST ha emergido como un modelo de diseño predominante para los servicios Web. En verdad, REST ha tenido tanto impacto en la Web que ha apartado enormemente al diseño de interfaces basado en SOAP y WSDL, por el hecho de que es un estilo considerablemente más fácil de utilizar.


REST no obtuvo mucha atención la primera vez que fue presentado en el por Roy Fielding en la Universidad de California, Irvine, en su disertación académica, "Architectural Styles and the Design of Network-based Software Architectures", que analiza un conjunto de principios arquitectónicos de software que emplean la Web como una plataforma para la computación distribuida. Ahora, años después de su presentación, han empezado aparecer las principales infraestructuras para REST, y se están desarrollando otras pues, por servirnos de un ejemplo, se ha anunciado que se marcha a convertir en una parte integral de Java™ seis en JSR-trescientos once.


Este artículo sugiere que, en su forma actual más pura, cuando atrae toda esta atención, las implementaciones concretas prosiguen cuatro principios básicos de diseño de servicios Web de REST:



  • Utilice métodos HTTP de forma explícita.

  • Sea sin estados.

  • Exponga los URIS como estructuras de directorios.

  • Transfiera XML, JavaScript Object Notation (JSON), o ambos.


Las próximas secciones amplían esos cuatro principios y proponen una razón técnica de por qué deberían ser importantes para los diseñadores de servicios Web de REST.


Utilice métodos HTTP de forma explícita


Una de las principales características de un servicio Web de RESTful es el uso explícito de métodos HTTP de una manera que prosiga el protocolo tal y como está definido por RFC dos mil seiscientos dieciseis. HTTP GET, por poner un ejemplo, se define como un método para producir datos, que está destinado a ser utilizado por una aplicación del cliente del servicio para recuperar un recurso, para traer datos desde un servidor Web o bien para ejecutar una consulta con la expectativa de que el servidor Web la busque y responda con un conjunto de recursos que coincidan.


REST pide a los desarrolladores que usen HTTP de forma explícita y de una manera que sea coherente con la definición del protocolo. Este principio básico del diseño de REST establece una correlación individual entre las operaciones de crear, leer, actualizar y borrar (CRUD) y los métodos HTTP. Según esta correlación:



  • Para crear un recurso en el servidor hay que usar un POST.

  • Para recuperar un recurso hay que emplear un GET.

  • Para mudar el estado de un recurso, o para actualizarlo, hay que usar un PUT.

  • Para suprimir o borrar un recurso hay que utilizar un DELETE.


Una poco afortunada falla de diseño inherente de muchas APIs Web es la utilización de métodos HTTP para fines no deseados. Por servirnos de un ejemplo, el URI de la solicitud en una solicitud HTTP GET, por norma general identifica un recurso específico. O bien la cadena de caracteres de una consulta de un URI de la solicitud incluye un conjunto de parámetros que define los criterios de búsqueda que el servidor emplea para encontrar un conjunto de recursos que coinciden. Al menos, así es cómo HTTP/1.1 RFC describe el GET. Pero, existen muchos casos de APIs Web no atractivas que utilizan HTTP GET para provocar algo transaccional en el servidor—por ejemplo, para añadir registros a una base de datos. En esos casos, GET para pedir el URI no se usa apropiadamente, cuando menos, no se emplea de la manera RESTful. Si la API Web utiliza GET para invocar procedimientos remotos, se parecerá a esto:


GET /adduser?name=Robert HTTP/1.1


No es un diseño muy atractivo, pues el método Web anterior aguanta una operación de cambio de estado sobre HTTP GET. Por ponerlo de otra manera, la petición HTTP GET anterior tiene efectos colaterales. Si se procesa adecuadamente, el resultado de la petición será añadir un usuario nuevo—en este caso de ejemplo, Robert—para el almacén de datos latente. El problema aquí es eminentemente semántico. Los servidores Web están diseñados para responder a las peticiones HTTP GET recuperando los recursos que coinciden con la senda (o los criterios de la consulta) del URI de la solicitud, y devuelven exactamente los mismos, o bien una representación de ellos, en una respuesta; no para añadir un registro a una base de datos. Utilizar GET de esta forma es inconsistente desde el punto de vista del empleo previsto del método del protocolo, y desde el punto de vista de los servidores Web conformes con HTTP/1.1.


Más allá de la semántica, el otro inconveniente con GET es que, para desencadenar el borrado, modificación o incorporación de un registro en una base de datos, o para mudar el estado por el lado del servidor de alguna manera, invita a herramientas para atrapar las memorias caché de la Web (crawlers) y a motores de búsqueda para hacer cambios por el lado del servidor sin intención, solo rastreando un link. Una forma fácil de superar este problema habitual es desplazar a etiquetas XML los nombres y los valores de los parámetros del URI de la petición. Las etiquetas resultantes, una representación XML de la entidad a crear, se pueden enviar en el cuerpo de una HTTP POST cuyo URI de la petición es el objeto primario de la entidad (vea los Listados 1 y dos).


El método anterior es un ejemplo de una petición RESTful: uso conveniente de HTTP POST y también inclusión de la carga útil en el cuerpo de la solicitud. En la parte receptora, la solicitud se puede procesar añadiendo el recurso que está contenido en el cuerpo como un subordinado del recurso que está identificado en el URI de la solicitud; en este caso, el recurso nuevo se debería añadir como objeto secundario de /users. Esta relación de contención entre la entidad nueva y su objeto primario, como se especifica en la petición POST, es análoga a la forma en la que un fichero es subordinado a su directorio primario. El cliente establece la relación entre la entidad y su objeto primario, y define el URI de la nueva entidad en la solicitud POST.


Posteriormente, una aplicación del cliente del servicio podrá conseguir una representación del recurso utilizando el nuevo URI, observando que el recurso está ubicado, cuando menos lógicamente, bajo /users, como se muestra en el Listado 3.


La utilización de GET de este modo es explícita, porque GET sólo se usa para la recuperación de datos. GET es una operación que no debería tener efectos colaterales, una propiedad también conocida como idempotence.


En los casos en los que una operación de actualización sea soportada a través de HTTP GET, también se deberá aplicar una refactorización afín de un método web, tal como se muestra en el Listado 4.


Esto cambia el atributo (o bien propiedad) name del recurso. Aunque, para dicha operación se puede usar una cadena de consulta, y el Listado cuatro es una operación operación simple, este patrón cadena-de-consulta-como-método-de-firma tiende a estropearse cuando se utiliza para operaciones más complejas. En tanto que su meta es utilizar los métodos HTTP de forma explícita, un enfoque más RESTful es enviar una solicitud HTTP PUT para actualizar el recurso, en vez de HTTP GET, por las mismas razones precedentes (vea el Listado cinco).


Utilizar PUT para sustituir el recurso original da una interfaz más limpia, que es congruente con los principios de REST y con la definición de los métodos HTTP. La solicitud PUT del Listado 5 es explícita en el sentido de que apunta al recurso que debe ser actualizado identificándolo en la petición de URI, y en el sentido de que trasfiere una nueva representación del recurso desde el usuario hacia el servidor en el cuerpo de una solicitud PUT, en lugar de transferir los atributos del recurso como un conjunto suelto de nombres y valores de parámetros sobre el URI de la solicitud. El Listado cinco también renombra el recurso de Robert a Bob, y, al hacerlo, cambia su URI a /users/Bob. asesor paginas web madrid de REST, las peticiones siguientes para el recurso que utiliza el URI viejo generarían un fallo estándar 404 No Encontrado.


Como principio general del diseño, ayuda a proseguir las indicaciones de REST para usar métodos HTTP de forma explícita utilizando nombres en los URIs, en lugar de verbos. En un servicio Web de RESTful, los verbos—POST, GET, PUT y DELETE—ya están definidos por el protocolo. También, idealmente, el servicio Web no debería delimitar más verbos o bien procedimientos recónditos, como /adduser o /updateuser, para mantener la interfaz extendida y para permitir que los clientes del servicio sean explícitos sobre las operaciones que invocan. Este principio general del diseño también se aplica al cuerpo de una solicitud HTTP, que está destinado a ser usado para transferir el estado del recurso, no para llevar el nombre de un método recóndito o bien de un procedimiento recóndito a invocar.


Sea sin estado


Los servicios Web de REST tienen que escalar para satisfacer las cada vez mayores demandas de alto rendimiento. Los clústeres de los servidores que tienen capacidades de balanceo de carga y de recuperación por fallo, los proxys y las puertas de link, generalmente, se disponen de una forma que forma la topología de un servicio, lo que permite reenviar las peticiones de un servidor a otro según se necesite, para reducir el tiempo de respuesta general de una llamada a un servicio web. Para emplear servidores intermediarios para prosperar la escala, los clientes del servicio de servicios Web de REST tienen que enviar solicitudes completas y también independientes; es decir, enviar solicitudes que incluyan todos los datos que se tienen que completar, para que los componentes de los servidores intermediarios puedan reenviar, redirigir y balancear la carga para no tener que mantener de forma local ningún estado entre las solicitudes.


Una solicitud completa y también independiente no requiere que el servidor recupere ningún tipo de contexto o estado de la aplicación, mientras procesa la solicitud. Las aplicaciones (o bien clientes) de los servicios web de REST incluyen, dentro de las cabeceras y cuerpos HTTP de una solicitud, todos y cada uno de los parámetros, contexto y datos que el componente por el lado del servidor precisa para producir una contestación. El no tener estado en este sentido mejora el rendimiento del servicio Web y simplifica el diseño y la implementación de los componentes por el lado del servidor, debido a que la ausencia de estado en el servidor elimina la necesidad de sincronizar los datos de la sesión con una aplicación externa.


La imagen 1 ilustra un servicio sin estado desde el que una aplicación puede pedir la siguiente página de un conjunto de resultados de múltiples páginas, asumiendo que el servicio realice el seguimiento de dónde lo deja la aplicación mientras navega por el conjunto. agencia marketing digital valladolid ño sin estado, el servicio acrecienta y almacena, en algún lugar, una variable previousPage para ser capaz de contestar a las peticiones de la siguiente.



Los servicios con estado como este se vuelven complicados. En una Plataforma de Java, los servicios con estado de los ambientes Enterprise Edition (Java EE) precisan de muchas consideraciones anteriores para guardar eficientemente y para permitir la sincronización de los datos de la sesión a lo largo de un clúster de contenedores de Java. En este género de ambientes, hay un inconveniente con el que los desarrolladores de servlet/JavaServer Pages (JSP) y Enterprise JavaBeans (EJB) están familiarizados, de forma frecuente tienen inconvenientes para hallar la raíz de la causa de una excepciónjava.io.NotSerializableException a lo largo de la replicación de la sesión. Este inconveniente, tanto si es lanzado por el contenedor del servlet a lo largo de una replicación HttpSession tal y como si es lanzado por el contenedor de EJB a lo largo de una replicación de EJB sin estado, es un problema que puede valer a los desarrolladores días de trabajo procurando identificar un objeto que no incorpora Serializable en un, a veces, complejo gráfico de objetos que forman el estado del servidor. Además, la sincronización de la sesión añade una sobrecarga, que afecta al desempeño del servidor.


Los componentes sin estado por el lado del servidor, por otra parte, son más fáciles de diseñar, escribir y distribuir a lo largo de los servidores que tienen la carga equilibrada. Un servicio sin estado no sólo tiene mejor rendimiento, traspasa la mayor parte de la responsabilidad de sostener el estado a la aplicación del usuario. En un servicio web de RESTful, el servidor es quien se encarga de producir respuestas y de proporcionar una interfaz que deje que el usuario mantenga por sí sólo el estado de la aplicación. Por ejemplo, en la petición de un conjunto de resultados de múltiples páginas, el cliente debería incluir el número actual de la página a recobrar en vez de simplemente solicitar la siguiente (vea la Imagen dos).



Un servicio web sin estado produce una respuesta que enlaza al número de la siguiente página del conjunto y deja que el cliente del servicio haga lo que deba hacer para preservar ese valor. Este aspecto del diseño de servicios web de RESTful Web se puede separar en dos puntos de responsabilidades, como una separación de alto nivel que clarifica cómo se puede mantener un servicio sin estado:


Servidor



  • Genera respuestas que incluyen links a otros recursos, para permitir que otras aplicaciones naveguen entre los recursos relacionados. diseño web sevilla precio de respuesta incorpora enlaces. De forma similar, si la petición se efectúa para un objeto secundario o un recurso contenedor, la respuesta típica de RESTful también podría incluir links a los objetos secundarios del primario o a recursos subordinados, a fin de que éstos permanezcan conectados.

  • Genera respuestas que señalan si se pueden guardar en la memoria caché, para progresar el desempeño al reducir el número de solicitudes de recursos duplicados y al suprimir absolutamente ciertas peticiones. El servidor lo hace incluyendo una cabecera de respuesta HTTP Cache-Control y Last-Modified (una fecha).


Aplicación del cliente



  • Utiliza la cabecera de la respuesta Cache-Control para determinar si guarda el recurso en la memoria caché (hacer una copia local del mismo). El usuario también lee la cabecera de la respuesta Last-Modified y envía de vuelta el valor de la data en una cabecera If-Modified-Since para consultar al servidor si el recurso ha cambiado. Esto se llama GET Condicional, y las 2 cabeceras van mano a mano en que la respuesta del servidor es un código trescientos cuatro estándar (No Cambiado), y omite el recurso actual pedido si no ha cambiado desde ese instante. Un código de respuesta HTTP 304 quiere decir que el usuario puede usar seguramente una copia local, guardada en la caché, de la representación del recurso como la más actualizada; en verdad, elude las siguientes solicitudes GET hasta el momento en que el recurso cambie.

  • Envía peticiones completas que se pueden atender de forma independiente respecto a las otras solicitudes. Esto requiere que el cliente utilice absolutamente las cabeceras HTTP tal y como lo especifica la interfaz del servicio Web, y que envíe representaciones completas de los recursos en el cuerpo de la solicitud. El cliente del servicio envía peticiones que hacen poquísimas suposiciones sobre las anteriores peticiones, la existencia de una sesión en el servidor, la capacidad del servidor de añadir contexto a una solicitud, o acerca del estado de una aplicación que se mantiene entre las solicitudes.


Esta colaboración entre la aplicación y el servicio del cliente del servicio es esencial a fin de que un servicio web de RESTful sea sin estado. Mejora el rendimiento al ahorrar ancho de banda y al minimizar el estado de la aplicación por el lado del servidor.


Exponga los URIs como estructuras de directorio.


Desde el punto de vista de las aplicaciones que se encargan de recursos, los URIs determinan lo intuitivo que será un servicio web de REST y si el servicio se va a emplear de formas que los diseñadores puedan adelantar. La tercera característica web de RESTful va sobre los URIs.


Los URIs de los servicios web de REST deberían ser intuitivos hasta el punto en que sean fáciles de adivinar. Piense en un URI que tenga un género de interfaz autodocumentada que requiera poca, o ninguna, explicación o bien referencia para que un desarrollador entienda a que apunta y para derivar los recursos relacionados. Con este fin, la estructura de un URI debería ser bastante clara, predecible y fácil de entender.


Una forma de conseguir este nivel de usabilidad es definir URIs de tipo estructura de directorio. Este género de URI es jerárquico, enraizado como una única senda y sus ramificaciones son subrutas que exponen las primordiales áreas del servicio. Según esta definición, un URI no es meramente una cadena de caracteres delimitada por barras oblicuas, sino más bien un árbol con ramas subordinadas y superiores que se conectan en los nodos. Por ejemplo, en un servicio de hebras de discusiones que reúne temas que varían desde Java hasta el papel, usted puede definir un conjunto estructurado de URIs de esta manera:


/discussion/topics/topic


La raíz, /discussion, tiene un nodo /topics bajo ella. Por debajo de eso hay una serie de nombres de temas, como cotilleos, tecnología, etcétera, y cada uno de ellos apunta a una hebra de una discusión. Dentro de esta estructura es fácil extraer hebras de discusiones simplemente escribiendo algo después de /topics/.


En algunos casos, la senda cara un recurso se presta singularmente bien para una estructura tipo directorio. Por ejemplo, tome los recursos organizados por la data, lo que es una buena combinación para utilizar la sintaxis jerárquica.


Este ejemplo es intuitivo pues se basa en reglas:


/discussion/2008/12/10/topic


El primer fragmento de la senda es un año de cuatro dígitos, el segundo fragmento de la ruta es un día de dos dígitos y el tercer fragmento es un mes de 2 dígitos. Puede parecer un tanto absurdo tener que explicarlo así, mas es el nivel de simplicidad que buscamos. Los humanos y las máquinas pueden producir fácilmente URIs estructurados como estos, pues se basan en reglas. Rellenar las unas partes de la senda en las ranuras de la sintaxis hace que sean buenos porque hay un patrón terminante desde el que componerlos:


/discussion/year/day/month/topic


Algunas directrices auxiliares interesantes mientras que se piensa sobre la estructura del URI para un servicio web de RESTful son:



  • Esconder las extensiones del fichero de la tecnología de los scripts por el lado del servidor (.jsp, .php, .asp), si las tuviese, para poder transportarlo a otro sitio sin mudar los URIs.

  • Mantenga todo en letra minúscula.

  • Sustituya los espacios con guiones o bien con subrayados (escoger un tipo).

  • Evite consultar las cadenas de caracteres tanto como pueda.

  • Si el URI solicitado es para una senda parcial, dé siempre y en toda circunstancia como respuesta una página o bien recurso predeterminado, en lugar de emplear el código cuatrocientos cuatro No Encontrado.


Los URIs también deberían ser estáticos, a fin de que cuando el recurso o bien la implementación del servicio cambien, el link prosiga siendo el mismo. Esto deja emplear marcadores. También es esencial que la relación entre los recursos que está codificada en los URIs siga siendo independiente de la forma en la que se representan las relaciones dónde estás están almacenadas.


Transfiera XML, JSON, o ambos


Una representación de recursos en general refleja el estado actual de un recurso y de sus atributos en el instante en el que una aplicación usuario la pide. En este sentido, las presentaciones de recursos son puras instantáneas en el tiempo. Esto podría ser una cosa tan fácil como la representación de un registro en una base de datos que está formada por una correlación entre nombres de columnas y etiquetas XML, dónde los valores de los elementos del XML contienen los valores de las filas. O bien, si el sistema tiene un modelo de datos, entonces, según esta definición, una representación de un recurso es una instantánea de los atributos de una de las cosas del modelo de datos de su sistema. Estas son las cosas que usted quiere que su servicio web de REST presente.


El último conjunto de limitaciones que va en el diseño de un servicio web de RESTful debe ver con el formato de los datos que la aplicación y el servicio intercambian en la carga útil de la solicitud/respuesta o bien en el cuerpo HTTP. Aquí es donde realmente compensa sostener las cosas sencillas, inteligibles por los humanos y conectadas.


Los objetos de su modelo de datos en general están relacionados de alguna forma, y las relaciones entre los objetos del modelo de datos (recursos) deberían estar reflejadas de manera que estén representadas para trasferirlas a una aplicación cliente. En el servicio de hebras de discusiones, un ejemplo de representaciones de recursos conectados podría incluir un tema de la discusión raíz, sus atributos y los links incorporados a las respuestas que se han proporcionado para ese tema.


Y, finalmente, para otorgar a las aplicaciones del cliente del servicio la capacidad de pedir un género de contenido específico que le venga mejor, edifique su servicio de manera que utilice la cabecera HTTP Accept incorporada, donde el valor de la cabecera es un tipo MIME. En la Tabla 1 se muestran ciertos tipos MIME habituales que usan los servicios de RESTful.


Esto permite que el servicio sea empleado por diferentes clientes del servicio que están escritos en diferentes lenguajes y que se ejecutan en diferentes plataformas y dispositivos. La utilización de los tipos MIME y de la cabecera HTTP Accept es un mecanismo que se conoce como negociación de contenido, que deja de los clientes escojan cuál es el formato de datos que es adecuado para ellos y minimiza el acoplamiento de datos entre el servicio y las aplicaciones que lo emplean.


Conclusión


REST no siempre y en toda circunstancia es la elección adecuada. Fue impuesto como una forma de diseñar servicios Web con menos dependencia del middleware patentado (por poner un ejemplo, un servidor de aplicaciones) que la que tienen los del tipo SOAP y los basados en WSDL. Y, de alguna manera, REST es regresar a la Web de la forma en la que era ya antes de la era de los grandes servidores de aplicaciones, a través de su énfasis en los primeros estándares, URI y HTTP de Internet. Como hemos vistos en los autodenominados principios del diseño de la interfaz de RESTful, XML sobre HTTP es una potente interfaz que permite que aplicaciones internas, como el JavaScript Asincrónico + interfaces de usuario adaptadas basadas en XML (Ajax), se conecten, manejen y consuman recursos fácilmente. En verdad, el perfecto ajuste entre Ajax y REST ha incrementado la cantidad de atención que REST está consiguiendo estos días.


Exponer los recursos de un sistema durante una API de RESTful es una forma flexible de suministrar diferentes tipos de aplicaciones en las que los datos tengan un formato estándar. Ayuda a satisfacer los requisitos de la integración que son críticos para construir sistemas en los que los datos se puedan combinar fácilmente (mashups), y para extender o construir un conjunto de servicios de RESTful básicos y crear algo considerablemente mayor. Este artículo tan sólo toca los aspectos básicos, mas, espero que le haya incitado a seguir explotando el tema.

Back to posts
This post has no comments - be the first one!

UNDER MAINTENANCE

XtGem Forum catalog