API rest

por Fran Iglesias

Las API REST permiten a aplicaciones, servicios y capas de aplicación comunicarse entre sí, independientemente de las tecnologías subyacentes.

Esta serie sobre API Rest tiene los siguientes artículos:

API-REST
Sirviendo API-REST 1
Sirviendo API-REST 2

¿Qué es API REST?

En general, una API (Interfaz de Programación de Aplicaciones) es un modo estándar de utilizar un servicio o una funcionalidad que proporciona un software. Cuando hablamos de API REST nos referimos a que esa funcionalidad es facilitada a través del protocolo HTTP y cumpliendo una serie de requisitos.

Y es importante resaltar la palabra protocolo porque si bien podemos crear API basadas en HTTP “a nuestro estilo”, las API REST se caracterizan por seguir el protocolo de manera estricta. Un buen artículo para profundizar es “Conceptos sobre APIs REST” de Asier Marqués, que lo explica con bastante detalles y claridad, incluyendo referencias a los RFC de HTTP.

Explicado de forma muy elemental, las API REST se basan en aprovechar lo que ya ofrece el protocolo HTTP para no reinventar la rueda en el modo en que se accede al API y se hace la entrega de los recursos solicitados. A grandes rasgos:

Utiliza el lenguaje de HTTP

HTTP define una serie de verbos (GET, PUT, POST, PATCH, DELETE) que tienen un significado preciso. Al interactuar con la API usando estos verbos ya estamos comunicando una intención específica al sistema servidor, que puede actuar en consecuencia. Estos son los verbos:

  • GET /recursos (Dame todos los recursos)
  • GET /recursos/123 (Dame el recurso 123)
  • POST /recursos (Crea un nuevo recurso)
  • PUT /recursos/123 (Modifica el recurso 123)
  • PATCH /recursos/123 (Modifica algún aspecto del recurso 123)
  • DELETE /recursos/123 (Elimina el recurso 123)

Utiliza los códigos de estado de HTTP

Por otro lado, el HTTP también ofrece una variedad de códigos de estado o resultado de las peticiones que enviamos. Por lo tanto, tampoco tenemos que inventar nada nuevo. Tanto si estamos creando una API como si la estamos consumiendo, el resultado puede expresarse con alguno de estos códigos. He aquí algunos de los más habituales:

  • 200: OK
  • 204: No se encuentran resultados.
  • 404: El recurso solicitado no existe.
  • 500: Error en el servidor.

Utiliza las cabeceras de HTTP

Por último, un tercer aspecto a considerar es el uso de las cabeceras HTTP, tanto estándar como personalizadas, para comunicar meta información sobre la petición. Por ejemplo: las cabeceras Accept (enviada por el consumidor) y Content-Type (enviada por el servidor) permiten una negociación del formato del contenido, de forma que el cliente puede indicar que quiere recibir los datos en JSON y, a su vez, el servidor le informa de que se los envía en ese formato. Por esa razón no tenemos que especificar el formato en una extensión o un parámetro.

Otra cabecera estándar como Link, permite al servidor indicar al consumidor cómo acceder a recursos relacionados, como información de paginación y mucha más. Eso se relaciona también con otro aspecto de las API REST que es el uso de hypermedia, que, hablando en plata, es proporcionar hipervínculos a los recursos relacionados de modo que el consumidor no tenga que calcularlos, sino simplemente utilizarlos.

Además, podemos hacer uso de cabeceras no estándar para pasar información al cliente sobre la petición sin interferir en los propios recursos.

Diseño de API

El diseño de API incluye definir las URI que identifican los recursos y en su diseño hay que tener en cuenta una serie de normas:

  • Los nombres de URI no deben indicar acciones, sino recursos. Las acciones vienen dadas por los verbos HTTP que vimos al principio. Por tanto, GET /recurso/123 y POST /recurso/123 indican acciones diferentes sobre el mismo recurso.
  • Las URI deben ser únicas para cada recurso.
  • Las URI no indican formato, es decir, no utilizamos extensiones para indicar en qué formato se solicitan o entregan los datos (se hace a través de las cabeceras HTTP).
  • Deben mantener una jerarquía lógica. Si vamos a indicar un recurso como “hijo” o perteneciente a otro recurso, debe hacerse en una secuencia lógica. Por ejemplo GET /autores/250/articulos/ nos permitiría solicitar los artículos del autor con id 250. Mientras que GET /articulos/123/autores nos permitiría solicitar los autores del artículo 123. Este es quizá el aspecto más difícil de definir, pues la secuencia lógica puede fundamentarse de maneras diferentes.
  • Para filtrar recursos usamos los parámetros de la petición, no en la URI. Por ejemplo: GET /articulos?mes=5&pagina=2 , pero no GET /articulos/mes/5/pagina/2.

Podrías usar otros diseños de API pero no serían REST. La ventaja de usar REST es que éste nos proporciona, por así decir, una gramática que permite que las API sean interpretables por los consumidores. Además, el protocolo nos aporta una serie de mecanismos que, como hemos visto, resuelven todos los problemas básicos que nos vamos a encontrar en la comunicación de cliente y servidor.

Todo esto no elimina la necesidad de documentar la API, la forma de utilizarla y de manejar los resultados que obtenemos.

Hay más elementos que tomar en consideración a la hora de implementar una API, que iré tratando en otras entradas. El hecho de que sean stateless, de que deberían servirse sobre HTTPS, como tratar la autenticación y CORS (el poder servir API REST entre dominios). Un buen punto de partida es este artículo sobre buenas prácticas, que ofrece indicaciones bastante prácticas.

En la próxima empezaré con un ejemplo de cómo servir una API con PHP.

Temas

good-practices

refactoring

php

testing

tdd

design-patterns

python

blogtober19

design-principles

tb-list

misc

bdd

legacy

golang

dungeon

ruby

tools

hexagonal

tips

software-design

ddd

books

bbdd

soft-skills

pulpoCon

oop

javascript

api

typescript

sql

ethics

agile

swift

java