Servicios Web de RESTful

Servicios Web de RESTful

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 usan, en los últimos años REST ha emergido como un modelo de diseño predominante para los servicios Web. De hecho, REST ha tenido tanto impacto en la Web que ha apartado enormemente al diseño de interfaces basado en SOAP y WSDL, porque es un estilo considerablemente más fácil de emplear.

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 utilizan 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 pues, por ejemplo, se ha anunciado que se va a convertir en una parte integral de Java™ 6 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 siguen 4 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 4 principios y proponen 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 primordiales 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 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 usado por una aplicación del usuario para recobrar 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 solicita 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 utilizar un POST.
  • Para recobrar un recurso hay que usar un GET.
  • Para mudar el estado de un recurso, o bien para actualizarlo, hay que utilizar un PUT.
  • Para quitar o bien borrar un recurso hay que usar 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 ejemplo, el URI de la solicitud en una petición HTTP GET, por norma general identifica un recurso específico. O bien la cadena de caracteres de una consulta de un URI de la petición 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. Cuando 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 desencadenar algo transaccional en el servidor—por ejemplo, para añadir registros a una base de datos. En esos casos, GET para solicitar el URI no se utiliza adecuadamente, al menos, no se usa de la forma RESTful. Si la API Web usa GET para invocar procedimientos recónditos, se parecerá a esto:

GET /adduser?name=Robert HTTP/1.1

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

Más allá de la semántica, el otro problema con GET es que, para provocar el borrado, modificación o bien incorporación de un registro en una base de datos, o bien para mudar el estado por el lado del servidor de alguna forma, invita a herramientas para apresar 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 precedente es un ejemplo de una petición RESTful: empleo 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 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 manera en la que un archivo es subordinado a su directorio primario. El usuario 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 usando el nuevo URI, observando que el recurso está ubicado, por lo menos lógicamente, bajo /users, como se muestra en el Listado tres.

La utilización de GET así 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 cuatro.

Esto cambia el atributo (o propiedad) name del recurso. Si bien, para dicha operación se puede utilizar 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 usar 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 exactamente las mismas razones precedentes (vea el Listado cinco).

Utilizar PUT para reemplazar el recurso original proporciona una interfaz más limpia, que es coherente con los principios de REST y con la definición de los métodos HTTP. La solicitud PUT del Listado cinco 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 transfiere una nueva representación del recurso desde el cliente del servicio hacia el servidor en el cuerpo de una solicitud PUT, en vez 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. En un servicio Web de REST, las peticiones posteriores para el recurso que usa el URI antiguo 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 usando 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 delimitar más verbos o bien procedimientos remotos, como /adduser o /updateuser, para sostener la interfaz generalizada 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 empleado para transferir el estado del recurso, no para llevar el nombre de un método remoto o de un procedimiento recóndito a invocar.

Back to top

2) 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 enlace, por norma general, se disponen de una forma 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 progresar la escala, los clientes de servicios Web de REST tienen que mandar solicitudes completas e independientes; esto es, mandar peticiones que incluyan todos los datos que se deben completar, para que los componentes de los servidores intermediarios puedan reenviar, redirigir y balancear la carga para no tener que sostener localmente ningún estado entre las peticiones.

Una petición completa e independiente no requiere que el servidor recupere ningún género de contexto o bien estado de la aplicación, mientras que procesa la petición. Las aplicaciones (o clientes) de los servicios web de REST incluyen, en 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 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 elimina la necesidad de acompasar 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 que navega por el conjunto. En este diseño sin estado, el servicio incrementa y almacena, en algún sitio, una variable previousPage para ser capaz de responder a las solicitudes de la siguiente.

Los servicios con estado como este se vuelven complicados. En una Plataforma de Java, los servicios con estado de los entornos Enterprise Edition (Java EE) requieren de muchas consideraciones previas para guardar eficazmente y para permitir la sincronización de los datos de la sesión durante un clúster de contenedores de Java. En este género de ambientes, hay un problema con el que los desarrolladores de servlet/JavaServer Pages (JSP) y Enterprise JavaBeans (EJB) están familiarizados, a menudo tienen inconvenientes para encontrar 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 durante una replicación de EJB sin estado, es un inconveniente que puede valer a los desarrolladores días de trabajo intentando 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 otro lado, son más fáciles de diseñar, escribir y repartir durante los servidores que tienen la carga equilibrada. Un servicio sin estado no sólo tiene mejor desempeño, traspasa la mayoría de la responsabilidad de sostener el estado a la aplicación del cliente del servicio. En un servicio web de RESTful, el servidor es quien se encarga de generar contestaciones y de suministrar una interfaz que permita que el cliente del servicio sostenga 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 usuario debería incluir el número actual de la página a recobrar en lugar de simplemente solicitar la siguiente (vea la Imagen dos).

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 haga lo que deba hacer para conservar ese valor. Este aspecto del diseño de servicios web de RESTful Web se puede desglosar en 2 puntos de responsabilidades, como una separación de alto nivel que aclara cómo se puede mantener un servicio sin estado:

Servidor

  • Genera contestaciones que incluyen enlaces a otros recursos, para permitir que otras aplicaciones naveguen entre los recursos relacionados. Este tipo de respuesta incorpora links. 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 bien a recursos subordinados, a fin de que éstos permanezcan conectados.
  • Genera contestaciones que indican si se pueden guardar en la memoria caché, para mejorar el desempeño al reducir el número de peticiones de recursos duplicados y al suprimir completamente ciertas peticiones. El servidor lo hace incluyendo una cabecera de contestación 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 usuario también lee la cabecera de la respuesta Last-Modified y envía de vuelta el valor de la fecha 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 contestación del servidor es un código trescientos cuatro estándar (No Modificado), y omite el recurso actual pedido si no ha alterado desde ese momento. Un código de respuesta HTTP trescientos cuatro quiere decir que el usuario puede emplear 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 solicitudes completas que se pueden atender de forma independiente respecto a las otras solicitudes. Esto requiere que el cliente del servicio utilice completamente 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 solicitud. El cliente envía peticiones que hacen poquísimas suposiciones sobre las precedentes solicitudes, la existencia de una sesión en el servidor, la capacidad del servidor de añadir contexto a una petición, o sobre el 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 para que un servicio web de RESTful sea sin estado. Mejora el desempeño al ahorrar ancho de banda y al minimizar 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 hacen cargo de recursos, los URIs determinan lo intuitivo que será un servicio web de REST y si el servicio se marcha a usar 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 bien ninguna, explicación o bien referencia a fin de 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 comprender.

Una forma de lograr este nivel de usabilidad es delimitar URIs de tipo estructura de directorio. Este género de URI es jerárquico, enraizado como una única ruta 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 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 sencillamente escribiendo algo después de /topics/.

En ciertos casos, la ruta hacia un recurso se presta singularmente bien para una estructura tipo directorio. Por servirnos de un ejemplo, tome los recursos organizados por la fecha, lo que es una buena combinación para utilizar la sintaxis jerárquica.

Este ejemplo es intuitivo por el hecho de que se basa en reglas:

/discussion/2008/12/10/topic

El primer fragmento de la ruta 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 este modo, mas es el nivel de simplicidad que buscamos. Los humanos y las máquinas pueden generar fácilmente URIs estructurados como estos, pues se fundamentan en reglas. Rellenar las unas partes de la senda en las ranuras de la sintaxis hace que sean buenos por el hecho de que hay un patrón definitivo desde el que componerlos:

/discussion/year/day/month/topic

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

  • Esconder las extensiones del archivo 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 cambiar 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, proporcione siempre como respuesta una página o recurso predeterminado, en vez de utilizar el código 404 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 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 forma en la que se representan las relaciones dónde estás están guardadas.

Back to top

4) Transfiera XML, JSON, o ambos

Una representación de recursos normalmente refleja el estado actual de un recurso y de sus atributos en el instante en el que una aplicación cliente la solicita. En este sentido, las presentaciones de recursos son meras 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 poseen 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 en el cuerpo HTTP. Aquí es donde verdaderamente 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 manera, y las relaciones entre los objetos del modelo de datos (recursos) deberían estar reflejadas de forma 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 enlaces incorporados a las respuestas que se han proporcionado para ese tema.

Y, por último, para otorgar a las aplicaciones del cliente la capacidad de solicitar un tipo 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 algunos tipos MIME habituales que emplean los servicios de RESTful.

Esto deja que el servicio sea usado 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 del servicio elijan cuál es el formato de datos que es conveniente 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 y en todo momento es la elección conveniente. 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 manera, REST es regresar a la Web de la manera 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 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. En verdad, el perfecto ajuste entre Ajax y REST ha aumentado la cantidad de atención que REST está consiguiendo estos días.

Exponer los recursos de un sistema a lo largo de una API de RESTful es una forma flexible de proporcionar 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 bien 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 continuar 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