Saltar a contenido

Overview

Overview

Una API de REST, o API de RESTful, es una interfaz de programación de aplicaciones (API o API web) que se ajusta a los límites de la arquitectura REST y permite la interacción con los servicios web de RESTful

Las API son conjuntos de definiciones y protocolos que se utilizan para diseñar e integrar el software de las aplicaciones.Suele considerarse como el contrato entre el proveedor de información y el usuario, donde se establece el contenido que se necesita por parte del consumidor (la llamada) y el que requiere el productor (la respuesta)

REST

REST no es un protocolo ni un estándar, sino más bien un conjunto de límites de arquitectura. Los desarrolladores de las API pueden implementarlo de distintas maneras.

Cuando el cliente envía una solicitud a través de una API de RESTful, está transfiere una representación del estado del recurso requerido a quien lo haya solicitado o al extremo. La información se entrega por medio de HTTP en uno de estos formatos: JSON (JavaScript Object Notation), HTML, XLT, Python, PHP o texto sin formato. JSON es el lenguaje de programación más popular, ya que tanto las máquinas como las personas lo pueden comprender y no depende de ningún lenguaje, a pesar de que su nombre indique lo contrario. También es necesario tener en cuenta otros aspectos. Los encabezados y los parámetros también son importantes en los métodos HTTP de una solicitud HTTP de la API de RESTful, ya que contienen información de identificación importante con respecto a los metadatos, la autorización, el identificador uniforme de recursos (URI), el almacenamiento en caché, las cookies y otros elementos de la solicitud. Hay encabezados de solicitud y de respuesta, pero cada uno tiene sus propios códigos de estado e información de conexión HTTP.

Acciones y URLs

Los fundamentales principios de REST Se basan en separar tu API en recursos lógicos. Estos recursos son manipulados usando peticiones HTTP donde el método (GET, POST, PUT, PATCH, DELETE) tienen un significado específico.

¿Pero qué puede hacer un recurso?

Bueno, estos deberían ser sustantivos (¡no verbos!) que tengan sentido desde una perspectiva del consumidor de la API. Aunque tus modelos internos pueden mapear cuidadosamente con los recursos, no es necesario que sea un mapeo uno-a-uno. La clave es no filtrar ningún detalle irrelevante de implementación. Por ejemplo, algunos de los sustantivos de SupportFu podrían ser ticket, usuario y grupo.

Una vez que tienes tus recursos definidos, necesitas identificar qué acciones aplican a ellos y cómo deberían relacionarse con tu API. Los principios REST proveen estrategias para manejar acciones CRUD usando métodos HTTP relacionados de la siguiente forma:

  • GET /tickets- Devuelve una lista de tickets
  • GET /tickets/12- Devuelve un ticket específico
  • POST /tickets- Crea un nuevo ticket
  • PUT /tickets/12- Actualiza el ticket #12
  • PATCH /tickets/12- Actualiza parcialmente el ticket #12
  • DELETE /tickets/12- Elimina el ticket #12

La grandeza de REST es que estás impulsando métodos HTTP existentes para implementar funcionalidades importantes en sólo un simple endpoint /tickets. No hay convención de nombres de métodos para seguir y la estructura URL es limpia y clara.

¿El nombre del Endpoint debería ser singular o plural?

La regla mantenlo-simple (keep-it-simple) aplica aquí. Si bien tu gramática interna te dirá que está mal describir una instancia única de un recurso utilizando el plural, la respuesta pragmática es mantener el formato de la URL consistente y siempre usar plural. No tener que lidiar con plurales irregulares (person/people, goose/geese) hace más simple la vida del consumidor de la API y es más sencillo para el proveedor de la API implementarla (como los más modernos frameworks manejarán nativamente /tickets y /tickets/12 bajo un controlador común).

¿Pero cómo lidiar con las relaciones?

Si una relación puede existir con un sólo recurso, los principios REST proveen una guía útil. Veamos esto con un ejemplo. Un ticket en SupportFu consiste en un número de mensajes. Estos mensajes pueden ser lógicamente mapeados al endpoint /tickets de la siguiente forma:

  • GET /tickets/12/messages - Devuelve una lista de mensajes para el ticket #12
  • GET /tickets/12/messages/5 - Devuelve el mensaje #5 para el ticket #12
  • POST /tickets/12/messages - Crea un nuevo mensaje en el ticket #12
  • PUT /tickets/12/messages/5 – Actualiza el mensaje #5 para el ticket #12
  • PATCH /tickets/12/messages/5 - Actualiza parcialmente el mensaje #5 para el ticket #12
  • DELETE /tickets/12/messages/5 - Borra el mensaje #5 para el ticket #12

¿Qué ocurre con las acciones que no corresponden a las operaciones CRUD?

  1. Reestructura la acción para que aparezca como un campo de un recurso. Esto funciona si la acción no toma parámetros. Por ejemplo, un acción “activate” puede ser asignada a un campo booleano activated y actualizado vía PATCH al recurso.
  2. Tratarlo como un sub-recurso con principios REST. Por ejemplo, la API de GitHub te permite “star a gist“(marcar como importante) con PUT /gists/:id/star y “unstar” (desmarcar) con DELETE /gists/:id/star.
  3. A veces realmente no tienes forma de mapear la acción a una estructura REST apropiada. Por ejemplo, una búsqueda multi-recurso no tiene sentido ser asignada a un endpoint de un recurso específico. En este caso, /search podría tener más sentido incluso si no es un sustantivo. Esto está BIEN – sólo realiza lo que sea correcto desde la perspectiva del consumidor de la API y asegúrate de que esté claramente documentado para evitar confusiones.

Filtrado, ordenación y búsqueda en los resultados

Lo mejor es mantener la URL base de recursos tan simple como sea posible. Filtros de resultados complejos, requisitos de ordenamiento y búsqueda avanzada (cuando se limita a un solo tipo de recurso) pueden ser implementados fácilmente como parámetros de consulta en la parte superior de la URL base.

Filtrado:

Usa un único parámetro de consulta por cada campo que implemente el filtro. Por ejemplo, cuando se pide una lista de tickets del endpoint /tickets, podrías querer limitarla a sólo los que están en estado abierto. Esto puede ser logrado con una petición como GET /tickets?state=open. En este caso, state es el parámetro de la consulta que implementa el filtro.

Ordenación:

Similar al filtrado, un parámetro genérico sort puede ser usado para describir las reglas de ordenamiento. Organiza los requerimientos de ordenamiento complejos permitiendo que el parámetro de ordenación sea tomado de una lista de campos separados por coma, cada uno con un posible negativo unario para implicar orden descendiente. Veamos algunos ejemplos:

  • GET /tickets?sort=-priority – Devuelve una lista de tickets en orden de prioridad descendente
  • GET /tickets?sort=-priority,created_at- Devuelve una lista de tickets en orden de prioridad descendente. Con una prioridad específica, los tickets más viejos son ordenados primero.

Búsqueda

Cuando una búsqueda completa sobre el texto es usada como un mecanismo de devolución de instancias de recurso para un tipo de recurso específico, puede ser expuesto en la API como un parámetro de consulta al endpoint del recurso. Digamos que. Las consultas de búsqueda deberían ser pasadas directamente al motor de búsqueda y la salida de la API deberían estar en el mismo formato que una lista de resultados normal.

Combinando todo esto, podemos construir consultas como:

  • GET /tickets?sort=-updated_at – Devuelve los tickets recientemente actualizados
  • GET /tickets?state=closed&sort;=-updated_at – Devuelve los tickets recientemente cerrados
  • GET /tickets?q=return&state;=open&sort;=-priority,created_at – Devuelve el ticket abierto de mayor prioridad que menciona la palabra ‘return’

Códigos de estado HTTP

HTTP define un set de significativos códigos de status que pueden ser devueltos por la API. Éstos pueden ser nivelados para ayudar a los consumidores de la API dirigir sus respuestas apropiadamente. A continuación les dejo una lista de los que definitivamente deberías utilizar:

  • 200 OK - Respuesta a un exitoso GET, PUT, PATCH o DELETE. Puede ser usado también para un POST que no resulta en una creación.
  • 201 Created – [Creada] Respuesta a un POST que resulta en una creación. Debería ser combinado con un encabezado Location, apuntando a la ubicación del nuevo recurso.
  • 204 No Content – [Sin Contenido] Respuesta a una petición exitosa que no devuelve un body (como una petición DELETE)
  • 304 Not Modified – [No Modificada] Usado cuando el cacheo de encabezados HTTP está activo
  • 400 Bad Request – [Petición Errónea] La petición está mal formada, como por ejemplo, si el contenido no fue bien parseado.
  • 401 Unauthorized– [Desautorizada] Cuando los detalles de autenticación son inválidos o no son otorgados. También útil para disparar un popup de autorización si la API es usada desde un navegador.
  • 403 Forbidden – [Prohibida] Cuando la autenticación es exitosa pero el usuario no tiene permiso al recurso en cuestión.
  • 404 Not Found – [No encontrada] Cuando un recurso no existente es solicitado.
  • 405 Method Not Allowed – [Método no permitido] Cuando un método HTTP que está siendo pedido no está permitido para el usuario autenticado.
  • 410 Gone – [Retirado] Indica que el recurso en ese endpoint ya no está disponible. Útil como una respuesta en blanco para viejas versiones de la API
  • 415 Unsupported Media Type – [Tipo de contenido no soportado] Si el tipo de contenido que solicita la petición es incorrecto
  • 422 Unprocessable Entity – [Entidad improcesable] Utilizada para errores de validación
  • 429 Too Many Requests – [Demasiadas peticiones] Cuando una petición es rechazada debido a la tasa límite.

Para más información consultar