
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.
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ÓN | SQL | HTTP |
---|---|---|
Crear | INSERTAR | PUT / POST |
Leer | SELECCIONE | OBTENER |
Actualizar | ACTUALIZAR | PUT / POST / PATCH |
Borrar | ELIMINAR | ELIMINAR |
Aunque GET
y DELETE
coordinar bien, POST
, PUT
, y PATCH
no son directamente sinónimo de una sola operación CRUD. Por ejemplo, POST
no 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.
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:
URI | MÉTODO | DESCRIPCIÓN |
---|---|---|
http://api.nordicapis.com/v1/blogposts | POST | Crea una nueva publicación de blog |
http://api.nordicapis.com/v1/blogposts/{id} | GET | Recupera una publicación de blog |
http://api.nordicapis.com/v1/blogposts/{id} | PUT | Actualiza una publicación de blog |
http://api.nordicapis.com/v1/blogposts/{id} | DELETE | Elimina la publicación del blog |
http://api.nordicapis.com/v1/blogposts/{id}/author | GET | Recupera el autor de la publicación del blog |
http://api.nordicapis.com/v1/blogposts/{id}/comments | GET | Recupera 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.
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.
- Servidor de cliente
- Apátrida
- Caché
- En capas
- Código a pedido (opcional)
- 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
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 PUT
solicitud 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 GET
al 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.
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.
0 Comentarios
Dejanos tu comentario para seguir mejorando!