Servicios Web de RESTful: Los aspectos básicos

Servicios Web de RESTful: Los aspectos básicos

15 Jul 2020 in

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 del servicio 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 desplazado enormemente al diseño de interfaces basado en SOAP y WSDL, por el hecho de que es un estilo sensiblemente más fácil de emplear.

REST no consiguió mucha atención la primera vez que fue presentado en el dos mil 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 examina un conjunto de principios arquitectónicos de software que usan la Web como una plataforma para la computación distribuida. Ahora, años después de su presentación, han empezado aparecer las primordiales infraestructuras para REST, y se están desarrollando otras por el hecho de que, por servirnos de un ejemplo, se ha anunciado que se va a transformar en una parte integral de Java™ seis en JSR-311.

Este artículo sugiere que, en su forma actual más pura, cuando atrae toda esta atención, las implementaciones específicas siguen 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 bien los dos.

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

Back to top

1) Utilice métodos HTTP de forma explícita

Una de las principales características de un servicio Web de RESTful es el empleo explícito de métodos HTTP de una manera que siga el protocolo tal 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 usuario 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 utilicen HTTP de forma explícita y de una forma 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 recobrar un recurso hay que utilizar un GET.
  • Para cambiar el estado de un recurso, o para actualizarlo, hay que emplear un PUT.
  • Para suprimir o bien borrar un recurso hay que emplear un DELETE.

Una desafortunada 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 petición en una petición HTTP GET, generalmente 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 hallar un conjunto de recursos que coinciden. Cuando menos, así es cómo HTTP/1.1 RFC describe el GET. Mas, existen muchos casos de APIs Web no atractivas que emplean HTTP GET para desencadenar 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 emplea adecuadamente, cuando menos, no se usa de la forma RESTful. Si la API Web usa GET para invocar procedimientos remotos, se parecerá a esto:

GET /adduser?name=Robert HTTP/1.1

No es un diseño atractivísimo, pues el método Web anterior soporta una operación de cambio de estado sobre HTTP GET. Por ponerlo de otro modo, la petición HTTP GET precedente tiene efectos colaterales. Si se procesa apropiadamente, el resultado de la petición será añadir un usuario nuevo—en este caso, Robert—para el almacén de datos latente. El problema aquí es principalmente semántico. Los servidores Web están diseñados para contestar a las solicitudes HTTP GET recuperando los recursos que coinciden con la ruta (o bien los criterios de la consulta) del URI de la petición, y devuelven exactamente los mismos, o una representación de ellos, en una respuesta; no para añadir un registro a una base de datos. Usar GET así 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 provocar 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 forma, invita a herramientas para capturar 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 sencilla de superar este problema frecuente es desplazar a etiquetas XML los nombres y los valores de los parámetros del URI de la solicitud. 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 solicitud es el objeto primario de la entidad (vea los Listados 1 y 2).

El método anterior es un ejemplo de una solicitud RESTful: uso adecuado de HTTP POST y también inclusión de la carga útil en el cuerpo de la petición. 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 un caso así, 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 solicitud POST, es análoga a la forma en la que un archivo es subordinado a su directorio primario. El cliente del servicio establece la relación entre la entidad y su objeto primario, y define el URI de la nueva entidad en la petición POST.

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

La utilización de GET de esta manera es explícita, porque GET sólo se emplea 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) namedel recurso. Si bien, para dicha operación se puede usar una cadena de consulta, y el Listado 4 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 mandar una solicitud HTTP PUT para actualizar el recurso, en vez de HTTP GET, por exactamente las mismas razones precedentes (vea el Listado 5).

Utilizar PUT para sustituir el recurso original proporciona una interfaz más limpia, que es congruente con los principios de REST y con la definición de los métodos HTTP. La petición PUT del Listado cinco es explícita en el sentido de que apunta al recurso que ha de ser actualizado identificándolo en la solicitud de URI, y en el sentido de que transfiere una nueva representación del recurso desde el cliente cara el servidor en el cuerpo de una solicitud PUT, en vez de trasferir 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 Roberta Bob, y, al hacerlo, cambia su URI a /users/Bob. En un servicio Web de REST, las solicitudes posteriores para el recurso que utiliza el URI viejo generarían un error 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 vez 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 acotar más verbos o bien procedimientos recónditos, como /addusero /updateuser, para sostener la interfaz extendida y para dejar que los clientes sean explícitos acerca de las operaciones que invocan. Este principio general del diseño también se aplica al cuerpo de una petición HTTP, que está destinado a ser usado para trasferir el estado del recurso, no para llevar el nombre de un método remoto o de un procedimiento remoto a invocar.

Back to top

2) Sea sin estado

Los servicios Web de REST deben escalar para satisfacer las cada vez mayores demandas de alto desempeño. Los clústeres de los servidores que tienen capacidades de balanceo de carga y de recuperación por error, los proxys y las puertas de enlace, normalmente, se disponen de una manera que forma la topología de un servicio, lo que deja reenviar las peticiones de un servidor a otro según se necesite, para reducir el tiempo de contestación general de una llamada a un servicio web. Para emplear servidores intercesores para prosperar la escala, los clientes del servicio de servicios Web de REST deben enviar peticiones completas y también independientes; o sea, mandar peticiones que incluyan todos los datos que se deben completar, a fin de que los componentes de los servidores intercesores puedan reenviar, redirigir y balancear la carga para no tener que sostener de forma local ningún estado entre las solicitudes.

Una solicitud completa e 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 del servicio) de los servicios web de REST incluyen, en las cabeceras y cuerpos HTTP de una solicitud, todos los parámetros, contexto y datos que el componente por el lado del servidor necesita para generar una contestación. El no tener estado en este sentido mejora el desempeño del servicio Web y simplifica el diseño y la implementación de los componentes por el lado del servidor, dado a que la ausencia de estado en el servidor suprime 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 solicitar 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. En este diseño sin estado, el servicio incrementa y guarda, en algún lugar, una variable previousPagepara ser capaz de responder a las peticiones de la siguiente.

Los servicios con estado como este se vuelven difíciles. En una Plataforma de Java, los servicios con estado de los entornos Enterprise Edition (Java EE) precisan de muchas consideraciones previas para almacenar eficientemente y para permitir la sincronización de los datos de la sesión durante un clúster de contenedores de Java. En esta clase de ambientes, hay un problema con el que los desarrolladores de servlet/JavaServer Pages (JSP) y Enterprise JavaBeans (EJB) están familiarizados, de manera frecuente tienen inconvenientes para localizar la raíz de la causa de una excepción java.io.NotSerializableExceptiondurante la replicación de la sesión. Este problema, tanto si es lanzado por el contenedor del servlet durante una replicación HttpSessioncomo si es lanzado por el contenedor de EJB durante una replicación de EJB sin estado, es un problema que puede costar a los desarrolladores días de trabajo procurando identificar un objeto que no implementa Serializableen un, en ocasiones, complejo gráfico de objetos que constituyen 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 otro lado, son más fáciles de diseñar, escribir y repartir a lo largo de los servidores que tienen la carga equilibrada. Un servicio sin estado no sólo tiene mejor rendimiento, traspasa la mayoría de la responsabilidad de sostener el estado a la aplicación del cliente. En un servicio web de RESTful, el servidor es responsable de producir contestaciones y de proporcionar una interfaz que permita que el usuario sostenga por sí sólo el estado de la aplicación. Por poner un 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 sencillamente pedir la siguiente(vea la Imagen 2).

Un servicio web sin estado genera una respuesta que enlaza al número de la siguiente página del conjunto y deja que el cliente del servicio haga lo que tenga que hacer para preservar ese valor. Este aspecto del diseño de servicios web de RESTful Web se puede separar en 2 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 enlaces a otros recursos, para permitir que otras aplicaciones naveguen entre los recursos relacionados. Este tipo de contestación incorpora links. De forma similar, si la solicitud se efectúa para un objeto secundario o bien un recurso contenedor, la respuesta típica de RESTful también podría incluir links a los objetos secundarios del primario o bien 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 rendimiento al reducir el número de solicitudes de recursos duplicados y al eliminar totalmente ciertas peticiones. El servidor lo hace incluyendo una cabecera de respuesta HTTP Cache-Control y Last-Modified (una data).

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 cliente del servicio 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 preguntar al servidor si el recurso ha alterado. Esto se llama GET Condicional, y las 2 cabeceras van mano a mano en que la contestación del servidor es un código trescientos cuatro estándar (No Modificado), y omite el recurso actual solicitado si no ha cambiado desde ese momento. Un código de respuesta HTTP trescientos cuatro significa que el usuario puede utilizar de forma segura una copia local, guardada en la caché, de la representación del recurso como la más actualizada; en verdad, elude las siguientes peticiones 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 del servicio utilice totalmente las cabeceras HTTP tal como lo especifica la interfaz del servicio Web, y que envíe representaciones completas de los recursos en el cuerpo de la petición. El cliente del servicio envía peticiones que hacen poquísimas suposiciones acerca de las anteriores solicitudes, la existencia de una sesión en el servidor, la capacidad del servidor de añadir contexto a una solicitud, o bien sobre el estado de una aplicación que se sostiene entre las solicitudes.

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

Back to top

3) 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 comprenda 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 comprender.

Una forma de conseguir este nivel de usabilidad es delimitar 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 acotada por barras oblicuas, sino más bien un árbol con ramas subordinadas y superiores que se conectan en los nodos. Por poner un ejemplo, en un servicio de hebras de discusiones que reúne temas que varían desde Java hasta el papel, puede delimitar un conjunto estructurado de URIs de esta manera:

/discussion/topics/topic

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

En ciertos 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 usar la sintaxis jerárquica.

Este ejemplo es intuitivo porque 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 2 dígitos y el tercer fragmento es un mes de dos dígitos. Puede parecer un poco absurdo tener que explicarlo de esta manera, mas es el nivel de simplicidad que estamos buscando. Los humanos y las máquinas pueden producir fácilmente URIs estructurados como estos, por el hecho de que se basan en reglas. Rellenar las unas partes de la ruta en las ranuras de la sintaxis hace que sean buenos pues hay un patrón terminante desde el que componerlos:

/discussion/year/day/month/topic

Algunas indicaciones adicionales 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 lugar sin mudar los URIs.
  • Mantenga todo en letra minúscula.
  • Sustituya los espacios con guiones o bien con subrayados (seleccionar un tipo).
  • Evite consultar las cadenas de caracteres tanto como pueda.
  • Si el URI pedido es para una ruta parcial, proporcione siempre y en todo momento como contestación una página o recurso predeterminado, en lugar de usar el código cuatrocientos cuatro No Encontrado.

Los URIs también deberían ser estáticos, para que cuando el recurso o bien la implementación del servicio cambien, el link prosiga siendo exactamente el mismo. Esto deja usar marcadores. También es importante que la relación entre los recursos que está codificada en los URIs prosiga siendo independiente de la manera en la que se representan las relaciones dónde estás están guardadas.

Back to top

4) Transfiera XML, JSON, o bien ambos

Una representación de recursos por norma general refleja el estado actual de un recurso y de sus atributos en el momento en el que una aplicación usuario la solicita. 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, 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 restricciones que va en el diseño de un servicio web de RESTful tiene que ver con el formato de los datos que la aplicación y el servicio intercambian en la carga útil de la solicitud/respuesta o en el cuerpo HTTP. Aquí es donde verdaderamente compensa mantener las cosas sencillas, legibles 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 transferirlas a una aplicación cliente. En el servicio de hebras de discusiones, un caso de representaciones de recursos conectados podría incluir un tema de la discusión raíz, sus atributos y los links incorporados a las contestaciones que se han proporcionado para ese tema.

Y, por último, para proporcionar a las aplicaciones del usuario la capacidad de solicitar un género de contenido específico que le venga mejor, edifique su servicio de forma 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 frecuentes que utilizan los servicios de RESTful.

Esto permite que el servicio sea utilizado 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 modelos 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 utilizan.

Back to top

5) Conclusión

REST no siempre es la elección adecuada. Fue impuesto como una forma de diseñar servicios Web con menos dependencia del middleware patentado (por servirnos de un ejemplo, un servidor de aplicaciones) que la que tienen los del tipo SOAP y los basados en WSDL. Y, de alguna forma, REST es volver a la Web de la forma en la que era 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 deja que aplicaciones internas, como el JavaScript Asincrónico + interfaces de usuario personalizadas basadas en XML (Ajax), se conecten, manejen y consuman recursos fácilmente. De hecho, el perfecto ajuste entre Ajax y REST ha aumentado la cantidad de atención que REST está obteniendo estos días.

Exponer los recursos de un sistema a lo largo de una API de RESTful es una forma flexible de administrar 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 conjuntar 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 top
Share icon

ESTOS EXCLUSIVOS INFORMES GRATUITO REVELAN

7 SECRETOS DE EXPERTOS SEO QUE TE LLEVÁN AL 1#
7 SECRETOS DE EXPERTOS SEO QUE TE LLEVÁN AL 1# EN GOOGLE PARA GANAR 10.000s DE TRÁFICO DE CALIDAD GRATUITO - EN SÓLO 2 MESES
 

Los 7 pasos más poderosos para disparar tu ranking orgánico para ALCANZAR Y MANTENER un impresionante tráfico orgánico es TUYO.

Consigue gratis lo que el 1% de los expertos en SEO venden por miles de euros... y el otro 99% ni siquiera sabe que existe.


OBTEN MI INFORME GRATUITO
5 errores que debes evitar en tu sitio web de Drupal
Ebook - 5 errores que debes evitar en tu sitio web de Drupal (¡podrían costarte miles de euros!)
 

Este Ebook cubre 5 terribles errores que probablemente estés cometiendo ahora mismo con tu sitio web de Drupal.

¡Nº3 TE SORPRENDERÁ! Esta lectura de 10 minutos te ahorrará miles de euros.



OBTEN MI INFORME GRATUITO