REST
Introducción
REST (Representational State Transfer, o transferencia de estado representacional) es un estilo de arquitectura software utilizado para diseñar aplicaciones de web distribuidas.
Se basa en los siguientes principios o restricciones:
- Cliente - Servidor.
- Sin estado. La comunicación entre cliente y servidor debe ser sin estado.
- Sistema por capas. Entre el cliente y el servidor pueden existir múltiples capas como pasarelas, proxies o cortafuegos.
- Caché. Las respuestas del servidor se deben poder declarar como cacheables o no cacheables.
- Interfaz uniforme.
- Código a demanda. Los clientes pueden extender su funcionalidad descargando y ejecutando código a demanda. Esta restricción es opcional.
Las aplicaciones que cumplen estas restricciones se consideran RestFul.
El protocolo HTTP
Cuando se introduce una URL como https://www.google.com
en el navegador, se envía una solicitud (request) al servidor identificado por la URL. Este servidor responde con una respuesta (response). El formato de estas solicitudes y respuestas esta definido por el protocolo HTTP (Hyper Text Transfer Protocol).
Cuando se escribe una URL en el navegador, éste envía una petición GET
al servidor identificado. El servidor entonces contesta con una petición HTTP que contiene datos en HTML (Hyper Text Markup Language). El navegador toma este HTML y lo visualiza en la pantalla.
En el caso de cumplimentar un formulario cuando se da al botón de Enviar, la petición que se envía al servidor es POST
.
Métodos de solicitudes HTTP
El método utilizado en la solicitud HTTP indica qué acción se quiere realizar con dicha solicitud. Los más importantes son:
- GET. Recupera detalles de un recurso.
- POST. Crea un nuevo recurso.
- PUT. Actualiza un recurso existente.
- DELETE. Borra un recurso.
Otros son PATCH, OPTIONS o HEAD.
Códigos de estado de respuesta HTTP
En toda respuesta HTTP se envía siempre un código de estado. Algunos ejemplos son:
- 200: Éxito.
- 404: Página no encontrada.
Recursos
Un recurso es algo que puede ser accedido o manipulado.
Los recursos se pueden identificar mediante URI (Uniform Resource Identifier).
La sintaxis de un URI es: esquema:parte-específica-del-esquema
Representación
Los recursos RESTful son entidades abstractas. Los datos y metadatos que generan un recurso RESTful se tienene que serializar en una representación antes de enviarlos al cliente.
El mismo recurso puede tener varias representaciones. Estas representaciones pueden estar en formatos tipo texto (formatos HTML, XML o JSON) o binarios (PDFs, JPGEGs o MP4s). El cliente puede solicitar una representación en concreto, es lo que se denomina negociación del contenido.
💡 JSON se ha convertido en el formato estándar de facto para los servicios REST.
Métodos HTTP
En la Web, el estándar HTTP provee ocho métodos (o verbos) HTTP que permiten a los clientes interactuar y manipular recursos.
Los métodos más utilizados son GET, POST, PUT
y DELETE
.
Seguridad
Se dice que un método HTTP es seguro si no provoca ningún cambio en el estado del servidor, como GET
o HEAD
.
Idempotencia
Una operación se considera idempotente si produce el mismo estado del servidor tanto si se aplica una como varias veces. Los métodos GET, HEAD, PUT
y DELETE
son idempotentes.
GET
El método GET recupera la representación de un recurso.
Es seguro e idempotente, y las respuestas se pueden cachear.
Además de la representación, la respuesta a la petición GET incluye los metadatos asociados con el recurso. Estos metadatos se representan en una secuencia de valores clave-valor llamados cabeceras HTTP.
Ejemplo: Respuesta a una petición GET a http://blog.example.com/posts/1
:
]
HEAD
Se utiliza cuando un cliente quiere comprobar si un recurso está disponible y no le importa su representación. También se utiliza cuando el cliente quiere saber si existe una nueva versión del recurso antes de descargarlo.
El método HEAD solo devuelve los metadatos asociados al recurso, sin enviar la representación.
Es seguro e idempotente, y las respuestas se pueden cachear.
DELETE
Pide que se borre un recurso. Dependiendo de la implementación del servicio, el borrado puede ser físico o no.
Si el borrado es satisfactorio, las futuras peticiones GET recibirán un error Resource not found
vía el código de estado HTTP 403.
No es seguro, pero sí idempotente.
PUT
Permite a los clientes modificar el estado de un recurso. El cliente modifica el estado de un recurso y envía la representación actualizada al servidor usando un método PUT; al recibir la petición el servidor reemplaza el estado del recurso con el nuevo estado.
No es seguro, pero sí idempotente.
POST
Se usa para crear recursos. Habitualmente, se usa para crear recursos bajo subcolecciones (colecciones de recursos que existen bajo un recurso padre).
Al contrario que PUT; POST no necesita conocer la URI del recurso. El servidor es el responsable de asignar un ID al recurso y decidir la URI.
El método POST es muy flexible y se utiliza cuando ningún otro método resulta apropiado.
No es seguro ni idempotente.
PATCH
Se utiliza para hacer actualizaciones parciales de un recurso. Al contrario que PUT, no necesita enviar la representación completa del recurso.
Modelo de madurez de Richardson
Clasifica los servicios web basados en REST según cumplen los principios REST.
Nivel 0
Los servicios usan HTTP como mecanismo de transporte y hacen las llamadas a procedimientos remotos en una única URI.
Se suelen usar los métodos GET y POST.
Están en este nivel SOAP y los servicios web basados en XML-RPC.
Nivel 1
Se introducen múltiples URIs, uno por recurso. Los endpoints con funcionalidad compleja se descomponen en múltiples recursos. Sin embargo, los servicios en esta capan usan un verbo HTTP, normalmente POST, para realizar todas las operaciones.
Nivel 2
Los servicios de este nivel aprovechan el protocolo HTTP haciendo uso de los verbos y códigos de estado HTTP.
Los servicios web que implementan operaciones CRUD son ejemplos de nivel 2.
Nivel 3
Es el nivel más maduro para un servicio, se construye alrededor del concepto de HATEOAS. Los servicios en este nivel permiten el descubrimiento proveyendo respuestas que contienen enlaces a otros recursos relacionados, indicando al cliente qué hacer a continuación.
Construyendo una RESTful API
Una RESTful API bien diseñada permite a los usuarios finales consumir la API de forma sencilla y facilita su adopción.
A un alto nivel, los pasos para construir una RESTful API son:
- Recursos
Se empieza identificando los recursos de interés para los consumidores. A menudo, estos recursos coinciden con las entidades de la aplicación. - Puntos finales
El siguiente paso es diseñar URIs que mapeen los recursos a endpoints. - Acciones
Identificar los métodos HTTP que se pueden usar para realizar las operaciones en los recursos. - Respuestas
Identificar la representación soportada para las peticiones y responder con el código de estado apropiado.
Ejemplo de Rutas RESTful
Name | Path | HTTP Verb | Purpose | Mongoose Method |
---|---|---|---|---|
Index | /dogs | GET | List all dogs | Dog.find() |
New | /dogs/new | GET | Show new dog form | N/A |
Create | /dogs | POST | Create a new dog, then redirect somewhere | Dog.create() |
Show | /dogs/:id | GET | Show info about one specific dog | Dog.findById() |
Edit | /dogs/:id/edit | GET | Show edit form for one dog | Dog.findById() |
Update | /dogs/:id | PUT | Update particular dog, then redirect somewhere | Dog.findByIdAndUpdate() |
Destroy | /dogs/:id | DELETE | Delete a particular dog, then redirect somewhere | Dog.findByIdAndRemove() |
Seguridad
Existen seis formas de securizar servicios web:
Seguridad basada en la sesión
sequenceDiagram
autonumber
participant C as Cliente
participant F as Filtro Seguridad
participant S as Sesión
participant R as Api REST
C -) F : Solicita recurso protegido
F -) S : Busca contexto de seguridad
S -) F : Contexto no encontrado
F -) C : Página de login
C -) F : Usuario / contraseña
F -) F : Autenticación
F -) S : Guarda contexto de usuario
F -) F : Autorización
F -) R : Procesa solicitud
R -) C: Devuelve recurso protegido
- Viola el principio REST sin estado.
- Como el servidor maneja el estado del cliente, no es escalable.
Autenticación básica HTTP
sequenceDiagram
autonumber
participant C as Cliente
participant S as Servidor
C -) S : Solicita recurso protegido
S -) C : Exige autenticación básica
C -) C : Codifica Usuario / Contraseña
C -) S : Envía cadena codificada
S -) S : Decodifica y verifica
S -) C : Devuelve recurso protegido
- Se puede usar cuando hay interacción humana, pero no cuando unos servicios hablan con otros.
- Las credenciales de usuario se envían codificadas, pero no encriptadas.
Autenticación con resumen (digest)
sequenceDiagram
autonumber
participant C as Cliente
participant S as Servidor
C -) S : Solicita recurso protegido
S -) C : Exige autenticación con resumen (nonce, QOP)
C -) C : Calcula resumen
C -) S : Envía resumen
S -) S : Verifica y resume
S -) C : Devuelve recurso protegido
- Igual que la anterior, pero las credenciales de usuario se envían encriptadas.
- Se suele usar el algoritmo MD5 para los hash.
Seguridad basada en certificado
sequenceDiagram
autonumber
participant C as Cliente
participant S as Servidor
C -) S : Solicita recurso protegido
S -) C : Presenta certificado de servidor
C -) C : Verifica el certificado de servidor
C -) S : Responde con certificado cliente
S -) S : Verifica certificado cliente
S -) C : Devuelve recurso protegido
- Es más seguro que los sistemas anteriores, pero más costoso de gestionar y mantener.
- Se suele utilizar para sistemas grandes.
XAuth
sequenceDiagram
autonumber
participant U as Usuario
participant C as Cliente
participant S as Servidor
U -) C : Expresa intentés en acceder
C -) U : Solicita credenciales
U -) C : Envía usuario y contraseña
C -) S : Envía usuario y contraseña
S -) C : Token de acceso
C -) S : Solicita recurso protegido (Token de acceso)
S -) C : Devuelve recurso protegido
- Es un buen candidato cuando es la misma organización la que desarrolla tanto el cliente como la Api REST.
OAuth
sequenceDiagram
autonumber
participant U as Usuario
participant C as Cliente
participant SA as Servidor de Autorización
participant SR as Servidor de Recursos
U -) C : Expresa interés en usar la aplicación
C -) U : Solicita autorización
U -) SA : Autoriza la solicitud
SA -) C : Concede autorización
C -) SA : Solicita token de acceso
SA -) C: Concede token de acceso
C -) SR: Token de acceso
SR -) C: Recurso protegido
- El cliente debe registrarse en el Servidor de autorización.
Referencias
- Balaji Varanasi Sudha Belida - Spring REST
- Udemy - Learn Spring 5