Si has llegado hasta aquí es porque quieres aprender un poco sobre esta arquitectura y probablemente tengas pocas nociones sobre esto. De lo contrario, te recomiendo que no sigas leyendo. Es un artículo para principiantes.
Tabla de contenidos
El problema con las API
Llegó el año 2000, y empezaron a verse de forma clara las ventajas de los Web Services para la comunicación entre sistemas. Entre aplicaciones web. Cliente-Servidor. En aquel entonces no existía ningún estándar sobre cómo diseñar una API. Se implementaban usando otros protocolos como SOAP. Difíciles de implementar. Pesados. Más complejos en todos los aspectos.
Entonces, un grupo de expertos liderado por Roy Fielding, creó la llamada arquitectura REST. Esto cambió por completo el desarrollo de servicios web hasta la fecha.
REpresentational State Transfer
Esto es lo que significan sus siglas. Se trata de una arquitectura para estandarizar comunicaciones web entre sistemas, logrando que se entiendan mucho mejor entre ellos. A los servicios que cumplen con este diseño se les llama servicios RESTful.
Cliente y Servidor
El servidor expone la API para que el cliente haga uso de ella. Por ejemplo, los servidores de Twitter o Instagram nos facilitan el formato de sus API y nosotros, desde una aplicación web o móvil, accedemos a las mismas para leer o incluso modificar información.
El cliente hace una petición, y el servidor envía una respuesta.
Una de las ventajas de REST es que cliente y servidor no tienen porqué depender del mismo código para entenderse intercambiando mensajes. El servidor puede actualizarse y cambiar, sin que el cliente tenga que hacerlo. Y al revés. Mientras no cambie el formato de los mensajes, no hay problema.
Sistemas Stateless (sin estado)
Antes que nada es importante saber qué significa que un sistema no tenga estado. En una arquitectura REST, cuando se comunican servidor con cliente, estos no necesitan saber en qué estado se encuentra cada uno. Entienden igualmente el mensaje. Ambos pueden entenderlo sin tener en cuenta los anteriores. La base de la arquitectura REST define una interacción orientada a recursos.
Estructura de las comunicaciones
La arquitectura REST se basa en que el cliente envía peticiones para recuperar o modificar recursos, y el servidor responde con el resultado, que puede ser con los datos que hemos pedido o el estado de la petición.
Una petición está formada por:
- Un verbo HTTP que define la operación a realizar.
- Una cabecera o header que incluye información sobre la petición.
- Una ruta o path hacia un recurso.
- El cuerpo del mensaje o body con los datos de la petición.
Verbos HTTP
Existen 4 verbos principales que forman parte de las peticiones HTTP para interactuar con una API REST, estos son:
-
GET
Para recuperar información sobre un recurso específico. -
POST
Para crear un nuevo recurso. -
PUT
Actualizar un recurso -
DELETE
Eliminar un recurso
Por ejemplo, en el caso de una API sobre películas.
GET: Consulta y lee información sobre películas.
“/movies” nos permite acceder a todas ellas
“/movies/419” accedemos a la película con ID 419
GET https://www.domain.com/movies/419
Respuesta:
Status Code - 200 (OK)
{
"id": 419,
"title": "Eraserhead",
"year": "1977"
}
POST: Crea una nueva película
“/movies”
POST https://www.domain.com/movies
Respuesta:
Status Code - 201 (CREATED)
{
"movie": {
"id": 419,
"title": "Eraserhead",
"year": "1977"
}
}
PUT: Actualiza los datos de una película
“/movies/419” Actualizamos los datos de la película con id: 419
PUT https://www.domain.com/movies/419
Respuesta:
Status Code - 200 (OK)
DELETE: Elimina una película
“/movies/419” Elimina la película con id: 419
DELETE https://www.domain.com/movies/419
Respuesta:
Status Code - 204 (NO CONTENT)
Con esto deberíamos ofrecer las 4 funciones básicas de un modelo de datos. También conocidas con las siglas CRUD. Crear (Create), Leer (Read), Actualizar (Update) y Eliminar (Delete).
Cabeceras (headers) y parámetros Accept
A lo que he explicado le falta un detalle. Las cabeceras a incluir en las peticiones. El cliente debe enviar un tipo de contenido que el servidor sea capaz de entender. Para esto sirve el campo Accept. Se asegura que el servidor no enviará contenido que el cliente no pueda interpretar. Las opciones a enviar son MIME Types. Estos se utilizan para identificar los tipos de contenido del campo Accept. Consisten en un tipo y un subtipo.
Un tipo puede ser “image”, y un subtipo “image/jpeg”. O bien “text/css” para contenido de estilos CSS o “text/plain” para texto plano.
Algunos ejemplos más:
image — image/png, image/jpeg, image/gif
audio — audio/wav, image/mpeg
video — video/mp4, video/ogg
application — application/json, application/pdf, application/xml, application/octet-stream
Por ejemplo, un cliente que quiera acceder al contenido de una película, podría enviar una petición como esta:
GET /movies/885
Accept: text/html, application/xhtml
Respuestas del servidor
Cuando termina la operación de la API en el servidor, este nos enviará el resultado junto con una serie de datos para que podamos interpretar el éxito o no de la operación y el tipo de datos que recibimos.
Content Types
Cuando el servidor envía un payload hacia el cliente, debe incluir una cabecera llamada content-type. Esto es para que el cliente sepa qué tipo de contenido le llega. Estos datos también son MIME Types, tal y como indicamos anteriormente. Y además, el MIME Type que nos envía el servidor debe coincidir con el que envía el cliente en la cabecera Accept.
Pongamos un ejemplo sencillo que lo explica todo mucho mejor.
Petición del cliente:
GET /movies/445 HTTP/1.1
Accept: text/html, application/xhtml
Respuesta del servidor:
HTTP/1.1 200 (OK)
Content-Type: text/html
Códigos de respuesta
Las respuestas del servidor deben contener códigos de estado para avisar al cliente del éxito o no de cada operación. Para cada verbo HTTP tenemos una serie de códigos esperados que nos indicarán la ejecución correcta de cada operación:
- GET: Código 200 (OK)
- POST: Cödigo 201 (CREATED)
- PUT : Código 200 (OK)
- DELETE : Código 204 (NO CONTENT)