Header Ads Widget

Ticker

6/recent/ticker-posts

Diseño de una verdadera máquina de estados REST


 Hay muchos conceptos erróneos en torno a qué es exactamente la Transferencia de Estado Representacional (REST). El principal de los cuales es el concepto de hipermedia , o definido en contexto completo, Hypermedia como motor del estado de la aplicación (HATEOAS).

Dejando de lado la jerga, el hipermedia es en realidad una idea valiosa que muchas API web autoproclamadas "RESTful" no cumplen. Hypermedia otorga una mayor importancia operativa a los recursos , ubicados en URI . Con una API de hipermedia, cuando se envía una solicitud a un URI, la respuesta enumera información sobre el estado de los recursos y las operaciones futuras aceptables, en esencia creando una máquina de estado que se puede manipular.

Hypermedia es realmente valioso, ya que puede crear API más potentes que alivian la necesidad de control de versiones de API. Pero esta es solo una de las muchas facetas que hacen que el verdadero diseño REST sea increíble.

Hoy, dedicamos tiempo a definir qué es exactamente REST y qué no es. Dirigido por RESTafarian Asbjørn Ulsberg, descubriremos la historia del diseño de información que ha llevado a REST y desacreditaremos algunas malas interpretaciones comunes del diseño REST.

También construiremos una máquina de estado simulada y ejemplos de comportamientos HTTP, demostrando cómo se podría usar hipermedia dentro de una API REST para activar estados en un dispositivo de cocina de IoT. En realidad, seguir las restricciones de REST mediante la creación de una API compatible con HATEOAS podría ser muy beneficioso para avanzar en la web, así que démosle el enfoque que se merece.

Lea también el artículo de seguimiento de Asbjørn Ulsberg: REST State Machine Revisited

La historia detrás de REST e Hypermedia

¿Puedes adivinar cuántos años tiene el concepto de hipermedia? Tiene casi 80 años. Así es, en 1941, el autor argentino Jorge Luis Borges escribió El jardín de senderos que se bifurcan , un manuscrito que contenía páginas que se referenciaban entre sí; posiblemente la primera forma de hipertexto . Desde Bioshock hasta Goosebumps , elige tu estilo de aventura, el entretenimiento y los datos relacionales se han convertido en algo común, pero en  la  época de Borges , el libro no tenía precedentes. Algunos otros avances importantes que han llevado a REST son:

  • 1963 : Ted Nelson acuña los términos hipertexto e hipermedia .
  • 1968 : Douglas Engelbart estrena el sistema en línea en la madre de todas las demostraciones, que fue la primera aplicación digital de hipertexto, que incluía señalar con el mouse, editar texto, entorno de ventana y más, esencialmente dando origen al procesamiento de texto moderno.
  • 1987 : Bill Atkinson, empleado de Apple, crea HyperCard, creando la primera implementación exitosa de hipermedia antes de la World Wide Web.
  • 1989 : Tim Berners-Lee crea la World Wide Web en el CERN, implementando la primera implementación exitosa del Protocolo de transferencia de hipertexto (HTTP) entre un cliente y un servidor.
  • 2000 : Roy Fielding, coautor de la especificación HTTP y URI, escribe una tesis doctoral titulada Estilos arquitectónicos y diseño de arquitecturas de software basadas en redes . En el Capítulo 5 describe la Transferencia de Estado Representacional, o como comúnmente la llamamos, REST .

Esta publicación se inspiró en una charla impartida por Asbjørn Ulsberg en la Cumbre de la plataforma de API nórdicas de 2016. Míralo aquí:

¿Cómo definimos REST?

Entonces, ¿qué es REST? Es difícil abordar todos los aspectos técnicos en una sola publicación de blog, así que respondamos primero a cuatro conceptos erróneos para comprender qué no es REST .

Concepto erróneo común # 1: REST es solo CRUD.

CRUD , o Crear, Leer, Actualizar y Eliminar, se ha convertido en un acrónimo distintivo entre los profesionales de la gestión de datos, ya que representa las cuatro acciones básicas para comunicarse con una base de datos. Aunque CRUD se asigna limpiamente con acciones SQL, como podemos ver claramente a continuación, no se asigna bien a los métodos HTTP:

OPERACIÓNSQLHTTP
CrearINSERTARPUT / POST
LeerSELECCIONEOBTENER
ActualizarACTUALIZARPUT / POST / PATCH
BorrarELIMINARELIMINAR

Aunque GETDELETEcoordinar bien, POSTPUT, y PATCHno son directamente sinónimo de una sola operación CRUD. Por ejemplo, POSTno necesariamente solo significa "Crear". En realidad, es un método muy versátil, tan versátil que todo el protocolo SOAP se canaliza a través del método POST cuando se usa con HTTP.

Dado que los métodos HTTP no se asignan claramente a CRUD, Ulsberg argumenta que los proveedores de API deberían considerar cómo podrían describir sus API de una manera diferente:

“No se limite a CRUD cuando diseñe una API REST. Debe leer la especificación y comprender la semántica de cada método, y usarlo correctamente ".

Todo se reduce a que REST es un estilo arquitectónico , no un protocolo. Entonces, llamar a una API HTTP que se comporte con operaciones CRUD "RESTful" es una falacia.

Vea nuestra página interactiva REST vs SOAP

Concepto erróneo común n. ° 2: algunas construcciones de URI son más RESTful que otras

Los identificadores uniformes de recursos ( URI ) son vitales para definir recursos y actuar sobre los recursos, y son un concepto central de REST. Sin embargo, muchos desarrolladores parecen pensar que pueden distinguir una API REST simplemente en función de cómo está estructurada la URI. ¿Puedes decir qué URI es más RESTful que los demás?

http://api.nordicapis.com/authors/contributor?author=doerrfeld

http://api.nordicapis.com/blogpost/getPostById?id=47

http://api.nordicapis.com/blogpost/47/edit-form

http://api.nordicapis.com/blogpost/47

http://api.nordicapis.com/128ndoels-8asdf-12d5-39d3

Contrariamente a la creencia popular, dentro de las pautas REST no existe una construcción de URI RESTful. Para REST, estos URI son simplemente identificadores opacos ; sí, son identificadores globales y únicos que se pueden usar para muchos propósitos. Sin embargo, sin conocer más contexto y el comportamiento que ocurre bajo el capó (cómo se ven los métodos, cómo se ve la solicitud, cuál es la respuesta, etc.) no hay forma de saber si estas son operaciones RESTful o no. Lo que es el URI en realidad no debería importar, por lo que cualquiera de los anteriores es tan bueno como el otro.

"Dado que solo las máquinas deberían leer los URI y ningún ser humano, no debería importar"

La multitud de diseños de API legibles por humanos probablemente esté lanzando tomates en este punto. Todo esto no quiere decir que no debas prestar atención a hacer que los URI sean legibles por humanos . Sin embargo, Ulsberg reconoce que no debe depender de que estén representados de ninguna manera en particular dentro del cliente.

Por ejemplo, supongamos que tenemos documentación muy básica para una API de publicación de blog de API nórdicas, como se identifica a continuación:

URIMÉTODODESCRIPCIÓN
http://api.nordicapis.com/v1/blogpostsPOSTCrea una nueva publicación de blog
http://api.nordicapis.com/v1/blogposts/{id}GETRecupera una publicación de blog
http://api.nordicapis.com/v1/blogposts/{id}PUTActualiza una publicación de blog
http://api.nordicapis.com/v1/blogposts/{id}DELETEElimina la publicación del blog
http://api.nordicapis.com/v1/blogposts/{id}/authorGETRecupera el autor de la publicación del blog
http://api.nordicapis.com/v1/blogposts/{id}/commentsGETRecupera comentarios de publicaciones de blog

El hecho de que hayamos enumerado un URI, un método y una descripción para cada una de nuestras llamadas a la API no significa que hayamos creado una API REST; acabamos de documentar nuestros URI como documentaríamos las operaciones de RPC. Stefan Tilkov llama a estas API de URI . Según Ulsberg, esto supone una gran carga para los clientes para comprender cómo construir estos URI y elimina mucha flexibilidad del servidor.

Relacionado: Cómo mejorar la experiencia de la API usando Hypermedia

Concepto erróneo n. ° 3: las API REST deben tener versiones

Imagínese si tuviéramos una tabla de base de datos llamada 'Referer'. Después de mucho uso, nos dimos cuenta de que el nombre de la base de datos estaba mal escrito y que teníamos que cambiarlo a 'Referrer'. Dado que los clientes ya han codificado el nombre de la tabla en sus declaraciones SQL, no puede actualizar la tabla, ya que esto significa que tendría que actualizar todos los clientes; sería muy complicado.

De manera similar, si quisiéramos cambiar uno de nuestros /blogposts/URI desde arriba, estaríamos en la misma situación complicada: tendríamos que actualizar todos los clientes. Esto lleva a crear una versión 2, actualizar la documentación y pedir a los clientes que actualicen todo. En resumen, tener versiones codificadas en el URI es un proceso doloroso.

En cuanto a la versión de las API web o no, la presentación principal de Roy Fielding para la Conferencia Evolve 2013 simplemente dice:

"NO"

Concepto erróneo n. ° 4: Hypermedia es opcional para las API REST

No. Como dijo el propio Roy Fielding en una entrevista de 2014 con Mike Amudsen :

“'Hipermedia como motor del estado de la aplicación' es una restricción REST. No es una opción. No es un ideal. El hipermedia es una limitación. Es decir, o lo haces o no estás haciendo DESCANSO ".

Entonces, ¿qué es hipermedia exactamente? Bueno, REST consta de 6 limitaciones principales. De estos, HATEOAS es posiblemente el más importante y exclusivo de la estipulación REST, pero también el menos comprendido.

  1. Servidor de cliente
  2. Apátrida
  3. Caché
  4. En capas
  5. Código a pedido (opcional)
  6. Interfaz uniforme
    • Identificación de recursos
    • Manipulación de recursos
    • Mensajes autodescriptivos
    • Hipermedia como motor del estado de la aplicación (HATEOAS)

Para entender HATEOAS, Ulsberg recomienda que apliquemos el mismo pensamiento propuesto por Don Norman en The Design of Everyday Things . Como una taza quiere ser sostenida y levantada, o un botón quiere ser pulsado hipermedia quiere decirle qué hacer con el recurso . Los hipermedia son enlaces y metadatos para operaciones que ayudan a los desarrolladores o máquinas a realizar acciones adicionales. Como dice Ulsberg:

"Si miras a los hipermedia como una receta de cómo se supone que se verá la próxima solicitud, comprenderás de qué se trata"

Ejemplo de máquina de estado: tostadora de IoT

Así que profundicemos en cómo se ve realmente la hipermedia. Para describir el hipermedia como el motor del estado de la aplicación, tomemos un ejemplo simple de una posible máquina de estado: una tostadora conectada que se puede manipular a través de Internet.

Una máquina de estado es un concepto dentro de la programación informática que se utiliza para describir una máquina que tiene un conjunto de estados, generalmente con eventos de entrada y salida. En este caso, nuestra tostadora comienza apagada. Una vez encendido, entra en estado de calentamiento. Luego alcanza su límite superior de temperatura y entra en un estado inactivo, lo que reduce la temperatura. Al estar inactivo, se enfría y vuelve a un estado de calor. Continúa este ciclo, manteniendo una temperatura constante hasta que se tuesta el pan, luego de lo cual se apaga.
¿Cómo podrías manipular una tostadora así a través de REST e hipermedia? Bueno, como describió Roy Fielding, los hipermedios son el motor del estado de la aplicación. Cada página de la web representa un solo estado de un solo recurso, que se puede obtener mediante una llamada GET. Está implícito que puede recuperar cualquier cosa con un ID en un URI. Entonces, primero llamemos a nuestra tostadora para ver qué obtenemos:

GET /toaster HTTP/1.1

La respuesta se parece a:

HTTP/1.1 200 OK
{ "Id": "/toaster", "state": "off", "operations": [{ "rel": "on", "method": "PUT", "href": "/toaster", "Expects": { "state": "on"} }] }

Como puede ver, tenemos una identificación en la parte superior para indicar con qué recurso nos estamos comunicando. Se muestra el estado actual, así como una lista de posibles operaciones que podemos realizar en la máquina.

Intentemos alterar realmente el estado de la tostadora. Enviaremos una PUTsolicitud HTTP para esto:

PUT /toaster HTTP/1.1

{
    "state": "on"
}

Nuestra respuesta se verá así:

HTTP/1.1 200 OK
{ "Id": "/toaster", "state": "on", "strength": 0, "operations": [ { "rel": "on", "method": "PUT", "href": "/toaster", "expects": { "state": "off" } }, { "rel": "strength", "method": "PUT", "href": /fcesj48fl29304d827434j "expects": { "strength": [1,2,3,4,5,6] } }] }

¡Ahora hemos encendido la tostadora! Sin embargo, como podemos ver arriba, la fuerza aún se establece en cero, por lo que aún no se está calentando. Veamos qué pasa cuando hacemos una llamada para afectar la operación de fuerza.

PUT /toaster HTTP/1.1
{ "strength": 3 }

Entonces, cuando ejecutamos esta operación de fuerza, vemos que el estado ha cambiado y la tostadora ahora se está calentando:

HTTP/1.1 200 OK
{ "Id": "/toaster", "state": "heating", "strength": 3, "operations": [ { "rel": "on", "method": "PUT", "href": "/toaster", "expects": { "state": "off" } }, { "rel": "strength", "method": "PUT", "href": /fcesj48fl29304d827434j "expects": { "strength": [1,2,3,4,5,6] } }] }

Todavía tenemos otras opciones, como se muestra en el hipermedia anterior. Podemos optar por apagarlo o ajustar la fuerza nuevamente. Pero en cambio, enviemos otro GETal ID de la tostadora.

HTTP/1.1 200 OK
{ "Id": "/toaster", "state": "idle", "strength": 3, "operations": [ { "rel": "on", "method": "PUT", "href": "/toaster", "expects": { "state": "off" } }, { "rel": "strength", "method": "PUT", "href": /fcesj48fl29304d827434j "expects": { "strength": [1,2,3,4,5,6] } }]
}

Desde nuestra última solicitud, la tostadora ha entrado en un estado inactivo . Puede ver que aún podemos optar por apagarlo o ajustar la temperatura de calentamiento con la operación de fuerza.

Espere unos minutos, y otra solicitud a la máquina de estado probablemente resultará en un estado de "apagado" que puede incluir ninguna operación, o "apagado" - el estado de reposo inicial con la lista de posibles operaciones aún en la respuesta.

Relacionado: Diseño de API evolucionables para la Web

Conclusión

La web funciona como una red de ideas interconectadas, vinculadas con hipertexto. Ulsberg cree que las API web deberían imitar esto y que una faceta importante al hacerlo es implementar hipermedia dentro de nuestras API. Para los recién llegados a REST, la creación de una API compatible con HATEOAS es una gran mejora con respecto a las API de estilo RPC:

Si usa hipermedia, puede agregar relaciones y enlaces, y operaciones a los recursos sin romper los clientes existentes y, al mismo tiempo, brindar nueva funcionalidad a los nuevos clientes.

Esto también significa repensar la postura tradicional sobre el control de versiones. Sobre las versiones, los pensamientos de Ulsberg se hacen eco de Fielding: no lo hagas . ¿Cuándo vio por última vez un número de versión en un sitio web? Como HTML no necesita un número de versión, JSON tampoco debería.

Al poner más énfasis en los recursos como máquinas de estado, podemos comunicar el estado actual a los consumidores a través de las operaciones que ponemos a disposición. Esto reduce el acoplamiento y en los dominios comerciales donde el estado de la aplicación consiste en muchos factores complejos e interdependientes, y hará que el cliente sea mucho más simple. Este es el poder del DESCANSO. Este es el poder de los hipermedia.

Publicar un comentario

0 Comentarios