Header Ads Widget

Ticker

6/recent/ticker-posts

Diseño de API evolucionables para la Web: interacción

 

Diseño de API evolucionables para la Web: interacción |  API nórdicas

Este es el segundo artículo de una serie que tiene como objetivo volver a poner el foco de las API web en la Web , en su arquitectura subyacente y en lo que significa crear API evolutivas para ella. En el artículo anterior, presentamos la arquitectura de la Web y su primer pilar: la identificación . Ahora, en este artículo, describimos un pilar crucial sobre el que descansa todo el intercambio de información a través de la Web: la Interacción .

Otros artículos de la serie Designing Evolvable APIs for the Web :

Aprovechar HTTP al máximo

HTTP (Protocolo de transferencia de hipertexto) es un protocolo cliente-servidor de nivel de aplicación, donde los clientes y los servidores interactúan intercambiando mensajes. Los clientes envían mensajes de solicitud a los servidores, identificando un recurso de destino y un método que define la operación que se realizará sobre ese recurso. Los servidores responden con mensajes de respuesta que contienen el estado de la operación (exitosa u otra), metadatos y representaciones. Ambos mensajes pueden tener metadatos sobre los mensajes o sobre las representaciones realizadas.

Interacción

Uno debe recordar que HTTP no es solo un protocolo de transporte de representación. Es un protocolo rico en funciones para sistemas distribuidos, que proporciona muchas funciones a nivel de aplicación que no deben ignorarse al diseñar API para la Web. Algunas de esas características son:

  • Un conjunto común de métodos con semántica independiente de recursos.
  • Un amplio conjunto de códigos de estado que se pueden utilizar para informar a los clientes del resultado de la solicitud.
  • Funciones de protocolo adicionales para manejar problemas de nivel de aplicación como almacenamiento en caché, control de acceso, simultaneidad optimista y tolerancia a fallas.

Métodos de solicitud HTTP

Un mensaje de solicitud se caracteriza por dos partes muy importantes. El destino, compuesto por un URI , identifica el recurso donde se debe realizar una operación. El método de solicitud define esta operación y es la fuente principal de la semántica de solicitud.

Una característica definitoria de HTTP es que el conjunto de métodos disponibles es siempre el mismo, independientemente del recurso de destino. Esto contrasta claramente con otros estilos arquitectónicos, como RPC (llamadas a procedimientos remotos) u objetos distribuidos, donde cada objetivo de solicitud tiene sus propias operaciones específicas.

El conjunto fijo de métodos disponibles es (descripciones adaptadas de RFC 7231 )

MÉTODODESCRIPCIÓN
OBTENERTransfiera una representación actual del recurso de destino.
CABEZAIgual que GET, pero solo transfiere la línea de estado y la sección de encabezado.
CORREORealice un procesamiento específico de recursos en la carga útil de la solicitud.
PONERReemplace todas las representaciones actuales del recurso de destino con la carga útil de la solicitud.
ELIMINARElimina todas las representaciones actuales del recurso de destino.
CONECTAREstablezca un túnel al servidor identificado por el recurso de destino.
OPCIONESDescribe las opciones de comunicación para el recurso de destino.
RASTRORealice una prueba de bucle de mensajes a lo largo de la ruta al recurso de destino.

 

Este conjunto de métodos uniforme no significa que todos los recursos deban admitir todos estos métodos. Por ejemplo, es posible que algunos recursos no se puedan eliminar, en cuyo caso el DELETEmétodo nunca tiene éxito cuando se aplica sobre ellos. El conjunto de métodos es fijo y también su semántica. Como ejemplo, la DELETEsemántica es la misma independientemente del recurso donde se aplica.

A primera vista podría parecer que este conjunto método uniforme sólo es útil para sistemas simples CRUD (Create-Read-Actualización-Delete), donde el POSTGETPUTDELETEse utilizan métodos para manipular las entradas en una base de datos. Sin embargo, esta vista ignora una característica importante de la Web y de HTTP: los recursos no se limitan a archivos o entradas en una base de datos.

Los recursos pueden representar procesos y no solo datos. Por ejemplo, un POSTrecurso a to a se puede utilizar para iniciar una operación de larga duración, cuyo estado se puede recuperar continuamente mediante GETla representación de un recurso de monitorización asociado. Esto se lleva a un contexto de IoT (Internet de las cosas), en el que las solicitudes HTTP a recursos como sensores o actuadores se pueden utilizar para desencadenar comportamientos en el mundo físico.

Para obtener más información sobre el diseño de IoT, lea: Uso compartido de datos en IoT

Códigos de estado HTTP

El protocolo HTTP proporciona un amplio conjunto de códigos de estado para representar diferentes resultados de procesamiento de solicitudes. En palabras de L. Richardson, M. Amundsen y S. Ruby en el libro RESTful Web APIs , los códigos de estado HTTP “representan un conjunto básico de semántica, definida en el más fundamental de todos los estándares API. No hay excusa para ignorar este regalo ".

Una API web debe aprovechar esta riqueza y utilizar correctamente los códigos de estado adecuados para los diferentes resultados del procesamiento de solicitudes. Por ejemplo, una API web no debería devolver un estado 200 (OK), si hubo un error de procesamiento.

En respuesta a una GETsolicitud, un servidor solo debe usar el estado 200 si el cuerpo del mensaje es de hecho la representación del recurso de destino de la solicitud. Entonces, a menos que “Vaya, algo salió mal” sea de hecho la representación del recurso de destino, no use un 200 en esa respuesta.

Tenga en cuenta también que son códigos de estado y no solo códigos de error , lo que significa que estos retornos pueden usarse para representar múltiples resultados de procesamiento. Los códigos de estado son números enteros de tres dígitos y se dividen en 5 clases .

HTTP 200–299: correcto

Los códigos de estado entre 200 y 299 informan que la solicitud se ejecutó con éxito. Sin embargo, el éxito viene en varios sabores. Algunos ejemplos incluyen:

  • Un 200 (OK) en una solicitud GET informa al cliente que el cuerpo de la respuesta sí contiene la representación del recurso de destino.
  • Un 201 (Creado) indica que la solicitud se realizó correctamente y que se creó un nuevo recurso.
  • Un 202 (aceptado) indica que la solicitud solo se aceptó correctamente y que su procesamiento continuará de forma asincrónica.

HTTP 400–499: incorrecto

Los códigos de estado entre 400 y 499 informan al cliente que la solicitud no se procesó correctamente debido a un error del cliente. De manera similar a los 200, existen múltiples variaciones, como:

  • Un 400 (solicitud incorrecta) es un código general para una solicitud incorrecta emitida por el cliente.
  • Un 401 (no autorizado) indica información de seguridad no válida o ausente, como credenciales de autenticación.
  • Un 403 (prohibido) informa al cliente que no está autorizado para realizar el método de solicitud sobre el recurso de destino.
  • Un 404 (No encontrado) indica que el recurso de destino no existe.

HTTP 500–599: error del servidor

Los códigos de estado entre 500 y 599 informan al cliente que la solicitud no se procesó correctamente debido a una falla del servidor. A continuación, se muestran algunos escenarios de ejemplo:

  • Error de infraestructura del servidor, como la incapacidad del servidor HTTP para conectarse a un servidor o servicio de base de datos back-end.
  • Error de programación que da como resultado una operación no válida, como una indexación fuera de los límites.
  • Falta de disponibilidad del servidor debido al mantenimiento programado.
  • Cuando el servidor actúa como un proxy inverso, como una puerta de enlace de API o un equilibrador de carga de nivel HTTP, se puede utilizar un 502 o un 504 para informar al cliente que se produjo un error en la solicitud al servidor back-end.

Aquí hay algunos ejemplos de errores que no son realmente culpa del servidor y, por lo tanto, no deberían usar un código 5xx:

  • Información de solicitud no válida, como un parámetro de cadena de consulta que debería ser convertible a un número entero y no lo es.
  • El estado del lado del servidor no es compatible con la operación solicitada, como un cliente que no tiene un método de pago configurado válido en una solicitud de compra.
  • Método HTTP solicitado no admitido.

Es decir, un código de estado 4xx es el más apropiado para representar el resultado del procesamiento en estos escenarios.

HTTP 1xx y 3xx

Las dos clases de códigos de estado restantes son informativas (1xx) y redirección (3xx). Los servidores utilizan la clase de estado 1xx para transmitir información de procesamiento intermedio antes de que se genere el mensaje de resultado. El ejemplo más común es el 100 (Continuar), que indica que el servidor ha aceptado la parte inicial de la solicitud y que el procesamiento continuará antes de que se produzca un mensaje de respuesta.

La segunda clase de estado (3xx) indica que el cliente debe realizar más solicitudes para completar la acción de solicitud. Un ejemplo típico es el estado 302 (Encontrado) que indica al servidor que el recurso de destino ahora está identificado por un URI diferente.

Consulte también: Arquitectura de un backend de API

3 beneficios del uso adecuado del código de estado HTTP

¿Cuáles son las ventajas de utilizar el código de estado HTTP adecuado? ¿Por qué no devolver un 200 (OK) para todo e incrustar el estado del resultado en una aplicación específica? Aquí hay algunas razones que pueden convencerlo de adoptar correctamente los códigos de estado HTTP.

  • Simplicidad de desarrollo : reduzca el esfuerzo necesario para consumir su API web reutilizando un conjunto de estados que deberían ser familiares y conocidos por los desarrolladores y bibliotecas de clientes HTTP.
  • Visibilidad operativa : un solo error 500 en el registro del servidor debería ser motivo de preocupación. Sin embargo, pueden ocurrir varios errores 4xx de forma rutinaria (por ejemplo, credenciales de autenticación caducadas). Tener la capacidad de diferenciar estas dos clases de errores simplemente mirando el entero del código de estado, sin tener que analizar el cuerpo de la respuesta, es una característica muy valiosa.
  • Visibilidad intermedia : por lo general, un intermedio no interpretará la carga útil de retorno, porque no tiene conocimiento del dominio, y basará su comportamiento en el estado de la respuesta. Por lo tanto, para que los intermediarios funcionen correctamente, se deben utilizar los códigos de estado adecuados. Por ejemplo, un caché del lado del cliente almacenará felizmente una respuesta 200 incluso si la carga útil es un seguimiento de pila de Java.
Nota: Los códigos de estado son uniformes en todos los recursos . No debería ser necesario documentar los códigos de estado por tipo de recurso.

Almacenamiento en caché

El almacenamiento en caché es otra área donde el protocolo HTTP muestra sus características a nivel de aplicación.
Para ilustrar eso, considere una API web que proporciona información que cambia lentamente, como datos de catálogo. Una forma de mejorar el comportamiento de dicha API es mediante el almacenamiento en caché de respuestas:

  • En el lado del servidor , esto significa que las solicitudes se pueden cumplir utilizando una respuesta almacenada previamente.
  • En el lado del cliente , esto significa que las solicitudes se manejarán localmente, utilizando respuestas recibidas previamente, sin necesidad de acceder a la red.

Hay varias formas de definir la política de almacenamiento en caché que podría utilizar un cliente. Una opción es fuera de banda , en la que la documentación de la API web indica cuánto tiempo es válido el contenido y se puede reutilizar. Una solución más dinámica podría basarse en la información de almacenamiento en caché específica de la aplicación agregada al contenido de la respuesta, como una propiedad "validUntil" en las representaciones JSON de la entrada del catálogo.

Sin embargo, una mejor alternativa a estos dos protocolos ad hoc y específicos de la aplicación es utilizar los mecanismos de almacenamiento en caché ya definidos por el protocolo HTTP. Esto tiene múltiples ventajas:

  • Conjunto más completo de semántica de almacenamiento en caché bien documentada, que incluye aspectos como la antigüedad y obsolescencia del contenido .
  • Conjunto de encabezados de solicitud y respuesta que permiten tanto a los clientes como a los servidores expresar la información de almacenamiento en caché de forma estándar.
  • Uso de componentes de almacenamiento en caché listos para usar, como cachés HTTP independientes (por ejemplo, Varnish) o bibliotecas de software, que ya comprenden estos encabezados y su semántica.

El Cache-Controlencabezado se puede utilizar en una respuesta para representar sus características de capacidad de almacenamiento en caché, es decir, si se puede almacenar en caché o no y durante cuánto tiempo.

HTTP/1.1 200 OK
Cache-Control: max-age=3600, public

En la respuesta anterior, el servidor le indica al cliente y a los intermediarios en la ruta de solicitud que el mensaje es válido para su uso durante los siguientes 3600 segundos. También establece que la respuesta se puede almacenar en una caché compartida pública. El Cache-Controlencabezado también se puede utilizar en los mensajes de solicitud para transmitir los requisitos de actualización del cliente, como la antigüedad máxima del contenido en caché o si el cliente está dispuesto a aceptar contenido obsoleto.

GET /catalogue/item HTTP/1.1
Host: api.example.com
Cache-Control: max-age=600

En el ejemplo anterior, el cliente usa el Cache-Controlpara indicar que está dispuesto a aceptar respuestas almacenadas en caché cuya antigüedad no sea superior a 10 minutos. Como desarrolladores de API web, debemos resistir la tentación de agregar información de almacenamiento en caché específica de la aplicación a nuestras cargas útiles y, en su lugar, intentar reutilizar lo que el protocolo HTTP ya define.

El almacenamiento en caché es solo una de las muchas funciones de nivel de aplicación que proporciona HTTP. Otros ejemplos son la gestión optimista de la concurrencia, utilizando solicitudes condicionales, tolerancia a fallos y autenticación.

Banner de publicación de blog de libros electrónicos sobre el ciclo de vida de la API

La interfaz uniforme y los intermediarios

HTTP define una interfaz uniforme , donde los métodos de solicitud aplicables, los códigos de estado de respuesta y los metadatos son independientes del tipo de recurso de destino. Esta uniformidad facilita el uso de componentes intermedios , como los proxies de caché, que pueden actuar sobre las solicitudes y respuestas sin conocer la semántica concreta de los recursos.

4.intermediarios

Como otro ejemplo, un servidor de almacenamiento en caché puede realizar de forma autónoma una solicitud GET porque este método es seguro : su ejecución no cambia el estado visible del servidor de origen relevante. Además, cualquier intermediario puede reintentar una solicitud PUT porque este método es idempotente : el efecto en el estado visible del servidor de múltiples solicitudes idénticas es el mismo que realizar una sola solicitud. Todas estas decisiones se pueden tomar sin ningún conocimiento de la semántica de los recursos. Esta independencia de recursos aumenta la utilidad de los intermediarios independientes del dominio, que se interponen entre los clientes y los servidores de origen.

Los intermediarios HTTP pueden ser útiles incluso en un mundo HTTPS, donde los intermediarios de la red no tienen visibilidad sobre los mensajes HTTP intercambiados. En el lado del cliente, los proxies independientes de la aplicación se pueden ejecutar en proceso o en la misma máquina para proporcionar funciones como almacenamiento en caché, reintentos automáticos o búsqueda previa. En el lado del servidor, el túnel TLS puede terminar en intermediarios de propósitos generales (proxies inversos) que brindan características como equilibrio de carga, almacenamiento en caché y seguridad. El creciente campo de API Gateways es un ejemplo del valor agregado por estos intermediarios HTTP en el contexto específico de las API web.

En cubierta: Tercera parte - Formatos

Con esto finaliza nuestro segundo artículo de esta serie, donde nuestro objetivo es volver a poner el foco de las API web en la Web, en su arquitectura subyacente y en lo que significa crear API evolutivas para ella. Nuestro próximo y último artículo de esta serie explorará el tercer pilar, los formatos , para ver qué significa la flexibilidad de formato para las API web.

Diseño de API evolucionables para la serie web

  

Publicar un comentario

0 Comentarios