Apidog

Plataforma de desarrollo de API colaborativa todo en uno

Diseño de API

Documentación de API

Depuración de API

Simulación de API

Prueba automatizada de API

Recursos en APIs REST: Explicación Clara

Iroro Chadere

Iroro Chadere

Updated on May 20, 2025

En el desarrollo web moderno, las API REST (Representational State Transfer) se han convertido en el estándar de facto para construir servicios web que son escalables, mantenibles y fáciles de entender. En el corazón mismo de cualquier API RESTful se encuentra un concepto fundamental: el recurso. Comprender qué son los recursos, cómo se identifican y cómo interactuamos con ellos es primordial para diseñar y consumir API REST de manera efectiva. Este artículo profundizará en la naturaleza de los recursos en las API REST, explorando sus características, su relación con las colecciones y las operaciones comunes que se realizan sobre ellos.

La idea central detrás de REST es que una API expone un conjunto de recursos, y los clientes interactúan con estos recursos enviando solicitudes a sus identificadores únicos. Pero, ¿qué constituye exactamente un "recurso"? En el contexto de una API REST, un recurso puede ser casi cualquier cosa que puedas nombrar. Podría ser una entidad tangible como un cliente, un producto o un pedido. También podría ser un concepto abstracto como un servicio, una transacción o un cálculo. La clave es que es un elemento de interés que puede ser identificado y manipulado.

Piensa en Internet mismo como una vasta colección de recursos. Cada página web, imagen, video o documento al que accedes en línea es un recurso, cada uno con su propia dirección única (URL). Las API REST adoptan esta misma filosofía. Ya sea un perfil de usuario en una plataforma de redes sociales, un libro específico en una biblioteca en línea o un pronóstico del tiempo para una ciudad en particular, cada uno es un recurso que la API pone a disposición.

💡
¿Quieres una excelente herramienta de prueba de API que genere documentación de API hermosa?

¿Quieres una plataforma integrada, todo en uno, para que tu equipo de desarrolladores trabaje en conjunto con máxima productividad?

¡Apidog cumple todas tus demandas y reemplaza a Postman a un precio mucho más asequible!
button

Identificando Recursos: El Papel de las URIs

Fundamentalmente, cada recurso en una API REST debe tener al menos un identificador único. Este identificador es típicamente un Uniform Resource Identifier (URI). La forma más común de URI utilizada en las API web es un Uniform Resource Locator (URL), que no solo identifica el recurso, sino que también proporciona un medio para localizarlo.

Por ejemplo, en una API para gestionar un blog, una publicación de blog específica podría identificarse mediante una URI como /posts/123. Aquí, /posts probablemente representa una colección de publicaciones, y 123 es el identificador único para una publicación en particular dentro de esa colección. De manera similar, un recurso de usuario podría identificarse mediante /users/john.doe.

El diseño de estas URIs es un aspecto crítico del diseño de API. Las URIs bien diseñadas son intuitivas, predecibles y fáciles de entender y usar para los desarrolladores. Deben actuar como una señal clara, indicando la naturaleza del recurso al que se accede. La buena práctica dicta usar sustantivos para representar recursos (por ejemplo, /products, /orders) en lugar de verbos (por ejemplo, /getProducts, /createOrder). Los métodos HTTP (GET, POST, PUT, DELETE) se utilizan luego para especificar la acción a realizar sobre el recurso identificado por la URI.

Recurso vs. Representación: Una Distinción Clave

Es importante comprender la diferencia entre un recurso y su representación. Un recurso es la entidad conceptual en sí misma: la "cosa" real (el cliente, el producto, la idea). Una representación, por otro lado, es una instantánea del estado de ese recurso en un momento particular, típicamente formateada en un tipo de medio específico como JSON (JavaScript Object Notation) o XML (eXtensible Markup Language).

Cuando un cliente solicita un recurso a una API, no recibe el recurso en sí (que es un concepto abstracto que reside en el servidor). En cambio, recibe una representación de ese recurso. Por ejemplo, si solicitas /users/jane.doe, la API podría devolver una representación JSON como:JSON

{
  "id": "jane.doe",
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@example.com",
  "dateJoined": "2023-01-15T10:00:00Z"
}

Este objeto JSON no es Jane Doe en sí misma; es una representación de sus datos tal como están almacenados por el sistema. El mismo recurso podría tener potencialmente múltiples representaciones. Por ejemplo, la API también podría ser capaz de proporcionar una representación XML del mismo usuario si el cliente lo solicita mediante negociación de contenido (utilizando encabezados HTTP como Accept).

El estado de un recurso puede cambiar con el tiempo. Si Jane Doe actualiza su dirección de correo electrónico, el recurso de usuario subyacente cambia. Las solicitudes posteriores para /users/jane.doe devolverán una nueva representación que refleje este estado actualizado. Aquí es donde entra en juego la parte de "Transferencia de Estado" de REST: los clientes interactúan con los recursos recuperando y manipulando su estado a través de estas representaciones.

Colecciones: Recursos que Contienen Otros Recursos

A menudo, los recursos se agrupan en colecciones. Una colección es en sí misma un recurso. Por ejemplo, /posts en nuestra API de blog es un recurso de colección que contiene recursos de publicaciones individuales. De manera similar, /users sería una colección de recursos de usuario.

Cuando un cliente envía una solicitud GET a una URI de colección como /products, la API típicamente devuelve una representación que lista los recursos miembros dentro de esa colección, a menudo con información resumida para cada uno. Esta lista podría verse así:JSON

[
  {
    "id": "prod_abc",
    "name": "Laptop Pro 15",
    "price": 1299.99,
    "link": "/products/prod_abc"
  },
  {
    "id": "prod_xyz",
    "name": "Wireless Mouse Ergonomic",
    "price": 39.99,
    "link": "/products/prod_xyz"
  },
  // ... más productos
]

Observa cómo cada elemento de la colección a menudo incluye un enlace (o su propia URI) al recurso individual, lo que permite al cliente navegar y recuperar los detalles completos de un producto específico si es necesario.

El diseño de URIs para colecciones y sus miembros sigue un patrón lógico. Típicamente:

  • /resources se refiere a la colección (por ejemplo, /orders).
  • /resources/{id} se refiere a un miembro específico dentro de esa colección (por ejemplo, /orders/567).

Esta estructura jerárquica hace que la API sea intuitiva y se alinee con la relación conceptual entre la colección y sus elementos.

Operaciones sobre Recursos y Colecciones

La interacción con recursos y colecciones en una API REST se logra a través de métodos HTTP estándar. Estos métodos definen las acciones a realizar. Los métodos más comunes son:

GET: Se utiliza para recuperar una representación de un recurso o una colección.

  • GET /posts recuperaría una lista de todas las publicaciones (la colección).
  • GET /posts/123 recuperaría la publicación específica con ID 123. Las solicitudes GET deben ser seguras, lo que significa que no deben tener efectos secundarios en el servidor; son puramente para recuperar datos. También deben ser idempotentes, lo que significa que múltiples solicitudes GET idénticas deben tener el mismo efecto que una sola solicitud (es decir, devolver la misma representación, asumiendo que el recurso no ha cambiado mientras tanto).

POST: Se utiliza principalmente para crear un nuevo recurso dentro de una colección. El cuerpo de la solicitud típicamente contiene la representación del nuevo recurso a crear.

  • POST /posts con un cuerpo de solicitud que contenga los detalles de una nueva publicación de blog (por ejemplo, título, contenido, autor) indicaría al servidor que cree esa nueva publicación. El servidor generalmente responde con un estado 201 Created y a menudo incluye la URI del recurso recién creado en el encabezado Location de la respuesta. Las solicitudes POST generalmente no son seguras (ya que crean un nuevo recurso) y no son idempotentes (múltiples solicitudes POST idénticas típicamente crearán múltiples recursos nuevos). POST también se puede utilizar para otras operaciones no idempotentes que no encajan perfectamente en otros métodos HTTP, como desencadenar un proceso o enviar datos para su procesamiento donde el resultado no es simplemente una actualización de un recurso identificable existente.

PUT: Se utiliza para actualizar un recurso existente por completo. El cuerpo de la solicitud debe contener la representación completa y nueva del recurso. Si el recurso identificado por la URI existe, se reemplaza con la nueva representación. Si no existe, algunas API pueden optar por crearlo (aunque este comportamiento puede variar).

  • PUT /posts/123 con un cuerpo de solicitud que contenga el título y contenido actualizados para la publicación 123 reemplazaría la publicación 123 existente con los nuevos datos. Las solicitudes PUT no son seguras (ya que modifican un recurso) pero son idempotentes. Enviar la misma solicitud PUT varias veces debería resultar en el mismo estado para el recurso. Por ejemplo, actualizar el título de una publicación a "Nuevo Título" varias veces sigue resultando en que el título sea "Nuevo Título".

DELETE: Se utiliza para eliminar un recurso.

  • DELETE /posts/123 eliminaría la publicación de blog con ID 123. Las solicitudes DELETE no son seguras (eliminan datos) pero son idempotentes. Eliminar un recurso varias veces debería tener el mismo resultado que eliminarlo una vez (el recurso desaparece). Las solicitudes DELETE posteriores a la misma URI podrían devolver un 404 Not Found o un 204 No Content.

PATCH: Se utiliza para actualizar parcialmente un recurso existente. A diferencia de PUT, que requiere que el cliente envíe la representación completa del recurso, PATCH permite enviar solo los cambios. Por ejemplo, para actualizar solo la dirección de correo electrónico de un usuario, una solicitud PATCH solo necesitaría incluir el nuevo correo electrónico.

  • PATCH /users/jane.doe con un cuerpo de solicitud como {"email": "new.email@example.com"} actualizaría solo la dirección de correo electrónico de Jane, dejando otros campos como su nombre sin cambios. Las solicitudes PATCH no son seguras. Su idempotencia puede ser debatida y depende de la naturaleza de la operación de parche. Por ejemplo, una operación PATCH que dice "agregar '!' a la descripción" no es idempotente, mientras que "establecer la descripción en 'nuevo valor'" sí lo es.

Recursos Singleton

Aunque las colecciones y sus miembros son comunes, a veces un recurso es una entidad independiente, a menudo denominada recurso "singleton". Un buen ejemplo podría ser la configuración de una aplicación específica o el estado actual de un sistema.

Por ejemplo, /application/configuration podría ser una URI para un recurso singleton que representa la configuración de la aplicación. Una solicitud GET a esta URI recuperaría la configuración actual, y una solicitud PUT podría usarse para actualizarla. No hay una "colección" de configuraciones en este contexto; simplemente existe la configuración.

De manera similar, /system/status podría representar el estado operativo actual del sistema.

Mejores Prácticas para Diseñar API Basadas en Recursos

Diseñar una API centrada en recursos implica más que solo identificar entidades y mapearlas a URIs. Varias mejores prácticas contribuyen a una API robusta y fácil de usar:

  1. Usar Sustantivos para URIs: Como se mencionó anteriormente, las URIs de recursos deben ser sustantivos (por ejemplo, /products, /users/{userId}/orders). Los verbos deben reservarse para los métodos HTTP.
  2. Nomenclatura Consistente de URIs: Utiliza una convención de nomenclatura consistente para tus URIs. Generalmente se prefieren los sustantivos en plural para las colecciones (por ejemplo, /customers en lugar de /customer). Utiliza guiones (-) para mejorar la legibilidad de segmentos de ruta largos (por ejemplo, /product-categories) en lugar de guiones bajos (_) o camelCase.
  3. Mantener las URIs Simples y Jerárquicas: Diseña URIs que reflejen las relaciones entre los recursos. Por ejemplo, /users/{userId}/accounts/{accountId} muestra claramente que una cuenta pertenece a un usuario. Sin embargo, evita anidamientos excesivamente profundos, que pueden hacer que las URIs sean difíciles de manejar.
  4. Sin Estado (Statelessness): Cada solicitud de un cliente al servidor debe contener toda la información necesaria para entender1 y procesar la solicitud. El servidor2 no debe almacenar ningún contexto del cliente entre solicitudes. Este es un principio fundamental de REST y contribuye a la escalabilidad.
  5. Aprovechar Correctamente los Métodos HTTP: Utiliza GET, POST, PUT, DELETE y PATCH de acuerdo con su semántica definida. No uses GET para modificar datos ni POST para recuperar datos cuando GET sea apropiado.
  6. Usar Códigos de Estado HTTP Apropiadamente: Devuelve códigos de estado HTTP estándar para indicar el resultado de una solicitud (por ejemplo, 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden,3 404 Not Found, 500 Internal Server Error). Esto proporciona una retroalimentación clara al cliente.
  7. Soportar Negociación de Contenido: Permite a los clientes especificar el formato de representación deseado (por ejemplo, JSON, XML) utilizando el encabezado Accept e indica el formato del cuerpo de la solicitud utilizando el encabezado Content-Type.
  8. Versionado: Planifica la evolución de la API implementando una estrategia de versionado (por ejemplo, /v1/products). Esto te permite introducir cambios disruptivos sin afectar a los clientes existentes.
  9. Proporcionar Representaciones de Error Significativas: Cuando ocurre un error, devuelve un mensaje de error útil en el cuerpo de la respuesta (típicamente JSON o XML) que explique qué salió mal.
  10. Hipermedia como Motor del Estado de la Aplicación (HATEOAS): Aunque no siempre se implementa por completo, HATEOAS es un principio clave de REST. Significa que las representaciones de los recursos deben incluir enlaces (controles de hipermedia) que permitan a los clientes descubrir acciones y recursos relacionados. Por ejemplo, una representación de un pedido podría incluir enlaces para cancelar el pedido, ver su estado de envío o ver los productos que contiene. Esto hace que la API sea más autodescubrible.

La Granularidad de los Recursos

Un desafío de diseño común es determinar la granularidad apropiada de tus recursos. ¿Debería una dirección ser un recurso separado o parte de un recurso de usuario? ¿Deberían los elementos de un pedido ser recursos distintos o estar incrustados dentro de un recurso de pedido?

No hay una única respuesta correcta; depende de los casos de uso específicos y de cómo los clientes interactuarán típicamente con los datos.

  • Recursos Separados: Si una entidad (como una dirección) puede ser creada, recuperada, actualizada o eliminada de forma independiente, o si es compartida entre múltiples otros recursos, a menudo tiene sentido modelarla como un recurso separado con su propia URI (por ejemplo, /addresses/{addressId}). Luego puedes vincularla desde otros recursos (por ejemplo, un recurso de usuario podría tener un campo addressId o un enlace a /addresses/{addressId}).
  • Recursos Incrustados/Sub-recursos: Si una entidad está estrechamente acoplada a un recurso padre y no tiene un ciclo de vida independiente, podría ser mejor modelarla como parte de la representación del recurso padre o como un sub-recurso accesible a través de una ruta como /users/{userId}/address. Esto puede simplificar las interacciones del cliente si la sub-entidad siempre se accede en el contexto de su padre.

La elección a menudo implica compensaciones:

  • Chattiness (Verbosidad): Muchos recursos de grano fino podrían llevar a más solicitudes HTTP (mayor verbosidad) si un cliente necesita ensamblar una imagen completa a partir de múltiples fuentes.
  • Duplicación/Complejidad de Datos: Incrustar recursos puede llevar a cargas útiles más grandes y a una posible duplicación o complejidad de datos si la información incrustada también está disponible como un recurso independiente.
  • Capacidad de Caché: Los recursos separados suelen ser más fáciles de almacenar en caché de forma independiente.
  • Atomicidad de las Operaciones: Las actualizaciones a un único recurso de grano grueso son inherentemente atómicas. Gestionar la atomicidad en múltiples actualizaciones de recursos de grano fino puede ser más complejo.

Una consideración cuidadosa de estos factores, junto con una profunda comprensión de cómo se utilizará la API, es crucial para tomar las decisiones correctas sobre la granularidad de los recursos.

💡
¿Quieres una excelente herramienta de prueba de API que genere documentación de API hermosa?

¿Quieres una plataforma integrada, todo en uno, para que tu equipo de desarrolladores trabaje en conjunto con máxima productividad?

¡Apidog cumple todas tus demandas y reemplaza a Postman a un precio mucho más asequible!
button

Conclusión

Los recursos son los bloques de construcción fundamentales de cualquier API RESTful. Representan las "cosas" que una API expone y permite a los clientes interactuar con ellas. Al asignar URIs únicas a los recursos, diferenciar entre un recurso y su representación, y organizar los recursos en colecciones lógicas, los desarrolladores pueden crear API que son intuitivas, escalables y que se adhieren a los principios de REST.

Comprender cómo definir, identificar y manipular recursos utilizando métodos HTTP estándar es esencial tanto para los diseñadores como para los consumidores de API. Junto con las mejores prácticas en el diseño de URIs, el uso apropiado de los códigos de estado HTTP y un enfoque reflexivo sobre la granularidad de los recursos, un modelo de recursos bien definido conduce a API que no solo son funcionales, sino también un placer trabajar con ellas. A medida que el panorama digital continúa evolucionando, los principios de la arquitectura orientada a recursos seguirán siendo una piedra angular de la comunicación efectiva de servicios web.