Read in English · Lire en français · Auf Deutsch lesen
Sección 0.6 de 0.8 · Principiante · 17 min de lectura
Las API, JSON y cómo trabajan juntos sistemas separados
Videolección
5 min · narrado en inglés, con subtítulosSolo escuchar (audio)
Leer la transcripción
Piensa en la carta de un restaurante y su camarero. La carta te dice exactamente qué puedes pedir. El camarero lleva tu pedido a la cocina y te trae el plato. Nunca entras en la cocina, y la cocina puede cambiar su forma de cocinar sin que te des cuenta, siempre que los platos de la carta sigan siendo los mismos. El software funciona con las API exactamente de esta manera.
Una API, o interfaz de programación de aplicaciones, es la forma definida en que una pieza de software le pide a otra que haga algo. La palabra clave es definida. Una API es un contrato, y la implementación que hay detrás permanece oculta y libre para cambiar. Algunas API se llaman dentro de un mismo programa, como llamadas normales a funciones. Una API web se llama a través de una red, a menudo entre organizaciones distintas, como una tienda que se comunica con un proveedor de pagos. Esa diferencia importa. Una llamada de red es mucho más lenta y puede fallar de formas en que no puede fallar una llamada a una función. La solicitud puede perderse, o la respuesta puede llegar después de que quien llama se haya rendido.
Así es una llamada a una API web. Una app de teléfono, el cliente, envía una solicitud GET por HTTPS para pedir a un proveedor de información meteorológica el pronóstico para Kigali. La solicitud llega a la API del clima: el contrato documentado del proveedor. Detrás de ella, los datos de pronóstico siguen siendo internos y ocultos. La API responde con un código de estado, doscientos, OK, y un cuerpo de datos en un formato llamado JSON. Fíjate en que el cliente solo ve el contrato. El proveedor puede cambiar todo lo que hay detrás, y la app nunca necesita saberlo.
La mayoría de las API web actuales siguen un estilo llamado REST. Una API expone recursos, como un cliente o un pedido, y cada uno tiene su propia URL. El cliente actúa sobre ellos con los métodos HTTP estándar, para obtener, crear, sustituir, cambiar o eliminar. Los mismos pocos verbos sirven para cualquier recurso. Los códigos de estado le dicen al cliente qué hacer a continuación. Reintentar sin cambios un error cuatrocientos volverá a fallar, pero reintentar un quinientos tres un poco más tarde puede tener éxito. Y los datos suelen viajar como JSON, un formato de texto sencillo de nombres y valores, listas, números y texto, que todos los lenguajes habituales pueden leer.
Sigamos a una app de viajes que quiere el pronóstico de mañana. Primero, lee el contrato: a qué dirección llamar, cómo enviar su clave de API, que identifica a la app, y un límite de sesenta solicitudes por minuto. Envía la solicitud por HTTPS, para que la clave y los datos vayan cifrados. Claves como esta nunca deben escribirse en el código fuente. Comprueba el estado. Doscientos significa éxito. Cuatrocientos uno significa que la clave es incorrecta, cuatrocientos veintinueve significa que hay que ir más despacio, y quinientos tres significa que hay que volver a intentarlo más tarde. Lee del JSON solo los campos que necesita, como la temperatura máxima de mañana y la probabilidad de lluvia. Y el paso que olvidan los principiantes: si no llega ninguna respuesta en unos tres segundos, muestra el último pronóstico que guardó, en lugar de una pantalla en blanco. Cualquier llamada de red puede ser lenta o fallar.
A veces un cliente necesita saber cuándo ocurre algo, como que un pago se complete. Podría sondear: preguntar "¿ya está?" una y otra vez. Eso desperdicia solicitudes, y aun así se entera tarde. Un webhook invierte el sentido. El proveedor envía un único mensaje a la propia dirección de la tienda cuando el pago se completa. Es rápido, pero la tienda debe comprobar que cada llamada es auténtica y estar preparada para recibir el mismo evento dos veces.
Hasta ahora, todas las llamadas han sido síncronas: quien llama espera la respuesta, como en una llamada telefónica. Eso es lo correcto cuando necesitas la respuesta ya, por ejemplo: ¿se ha aprobado este pago con tarjeta? La alternativa es la mensajería asíncrona, más parecida a enviar una carta por correo. Cuando se hace un pedido, el servicio de pedidos deja un mensaje en una cola y sigue con lo suyo. El servicio de correo lo recoge cuando está listo. Si el servicio de correo está caído durante una hora, los mensajes esperan en la cola en vez de perderse. El precio es que el emisor no sabe de inmediato si el trabajo ha tenido éxito.
Una vez que una API tiene usuarios, cambiarla es delicado. Añadir un campo opcional suele ser seguro. Pero cambiarle el nombre a uno o eliminarlo rompe todos los clientes que dependían de él. Por eso los proveedores versionan sus API, mantienen las versiones anteriores en funcionamiento durante un periodo publicado y anuncian los cambios con mucha antelación. Los proveedores también fijan límites de tasa, como cien solicitudes por minuto. Los clientes deben repartir sus solicitudes y retroceder cuando se les indique. Las API de terceros ahorran meses de trabajo, pero sus caídas se convierten en tus caídas. Así que oculta cada proveedor detrás de una pequeña interfaz propia, y planifica qué hacer cuando esté caído.
Las API son los contratos entre las partes de un sistema, hechos realidad. La sección completa incluye la solicitud y la respuesta completas, y más sobre claves y tokens. A continuación, en la Sección cero punto siete, veremos los servidores y la nube.
Lo que necesitas saber
- Una API es un contrato entre piezas de software: qué se puede solicitar, con qué entradas y qué se devuelve, mientras que la implementación que hay detrás permanece oculta y libre para cambiar.
- Las API en proceso son llamadas a funciones dentro de un programa; las API web cruzan una red, así que son más lentas y pueden fallar de formas en que no puede fallar una llamada a una función.
- Las API REST exponen recursos en URL, actúan sobre ellos con métodos HTTP (GET, POST, PUT, PATCH, DELETE), comunican los resultados con códigos de estado y normalmente intercambian JSON.
- Las claves de API identifican a la aplicación que llama; los tokens de acceso son credenciales de corta duración, a menudo en nombre de un usuario; ambos deben viajar solo por HTTPS y mantenerse fuera del código fuente.
- Un webhook es el proveedor llamando a una URL del cliente cuando ocurre un evento; los receptores deben verificar las firmas y gestionar los duplicados.
- Las llamadas síncronas esperan una respuesta; los mensajes asíncronos pasan por una cola, de modo que emisor y receptor no necesitan estar disponibles al mismo tiempo.
- Los cambios incompatibles perjudican a los clientes, así que las API se versionan, y los límites de tasa (HTTP 429) protegen a los proveedores; cada API de terceros es una dependencia que hay que aislar y tener en cuenta al planificar.
Qué es una API
Una API (interfaz de programación de aplicaciones) es la forma definida en que una pieza de software le pide a otra que haga algo. Enumera qué se puede solicitar, qué hay que proporcionar, qué se devuelve y qué puede salir mal. La palabra importante es definida: una API es un contrato. El proveedor promete mantenerla funcionando; el consumidor promete usar solo lo que describe.
Un restaurante es la analogía habitual. La carta enumera lo que puedes pedir y lo que lleva cada plato; el camarero lleva tu pedido a la cocina y te trae el resultado. No entras en la cocina, y no necesitas saber si el chef cocina con gas o con inducción. La cocina puede cambiar su equipamiento, su personal y sus proveedores a voluntad, siempre que los platos de la carta sigan llegando tal como se describen. La carta es la API, la cocina es la implementación, y la separación entre ambas es lo que permite que las dos partes cambien de forma independiente.
Es la misma idea que las interfaces de organizar el código, aplicada a todas las escalas. También es la razón por la que a los arquitectos les importan tanto las API: una API es el punto donde el trabajo de un equipo se encuentra con el de otro, y una vez que otros dependen de ella, cambiarla es costoso.
API en proceso y API web
Algunas API se llaman dentro de un mismo programa en ejecución. Cuando un código Python llama a json.loads(text), usa la API del módulo json de la biblioteca estándar: una llamada a una función que tarda nanosegundos y solo falla si la entrada es incorrecta. Las funciones y clases públicas de una biblioteca son su API en proceso.
Una API web se llama a través de una red, normalmente con HTTP (consulta cómo se comunican las computadoras). Quien llama y el proveedor pueden estar en máquinas distintas, estar escritos en lenguajes distintos y pertenecer a organizaciones distintas. Una app de banca para dispositivos móviles se comunica con la API web del banco; los servidores del banco se comunican con la API de una red de tarjetas; una tienda se comunica con la API de un proveedor de pagos.
La diferencia no es superficial. Una llamada de red es entre miles y millones de veces más lenta que una llamada a una función, y puede fallar de formas en que no puede fallar una llamada a una función: la red pierde la solicitud, el servidor está sobrecargado, la respuesta llega después de que quien llama se haya rendido, o la solicitud tuvo éxito pero la respuesta se perdió, de modo que quien llama no puede saber si el pago se realizó. Gran parte del diseño de sistemas distribuidos, que se trata en el Capítulo 6, consiste en convivir con estos fallos.
Una llamada a una API web
REST: recursos, URL y verbos
La mayoría de las API web actuales siguen el estilo llamado REST (Representational State Transfer), descrito por Roy Fielding en su tesis doctoral de 2000. Fielding definió REST como un conjunto de restricciones para grandes sistemas en red como la web; en el uso cotidiano, "una API REST" significa algo más sencillo: una API HTTP organizada en torno a recursos.
Un recurso es algo que la API expone: un cliente, un pedido, un pronóstico. Cada uno tiene una URL, como /orders/1042. Una colección de ellos también tiene una URL, como /orders. El cliente actúa sobre los recursos con los métodos HTTP estándar, lee el código de estado del resultado e intercambia datos en el cuerpo, normalmente como JSON. Por tanto, los mismos pocos verbos sirven para cualquier recurso, lo que hace que las API REST bien diseñadas sean predecibles.
Un recurso, los verbos estándar
| Solicitud | Significado | Estado habitual en caso de éxito |
|---|---|---|
GET /orders?customer=42 | Lista los pedidos, filtrados por un parámetro de consulta. Las lecturas nunca cambian nada. | 200 OK |
GET /orders/1042 | Obtiene un pedido. | 200 OK (o 404 Not Found si no existe ese pedido) |
POST /orders | Crea un pedido nuevo a partir del JSON del cuerpo de la solicitud. | 201 Created, con la URL del nuevo pedido |
PUT /orders/1042 | Sustituye el pedido 1042 por la representación enviada. | 200 OK o 204 No Content |
PATCH /orders/1042 | Cambia solo algunos campos, como la dirección de entrega. | 200 OK |
DELETE /orders/1042 | Cancela o elimina el pedido. | 204 No Content |
Los códigos de estado transmiten un significado según el cual puede actuar un programa cliente. Un código 4xx dice que el cliente ha hecho algo mal: 400 para una solicitud mal formada, 401 cuando faltan las credenciales o no son válidas, 403 cuando se sabe quién llama pero no tiene permiso, 404 cuando el recurso no existe, 429 cuando ha enviado demasiadas solicitudes. Un código 5xx dice que el servidor ha fallado: 500 para un error inesperado, 503 cuando no está disponible temporalmente. La distinción importa porque reintentar sin cambios una solicitud 4xx volverá a fallar, mientras que reintentar un 503 un poco más tarde puede tener éxito.
Los datos viajan como JSON (JavaScript Object Notation), un formato de texto normalizado como RFC 8259. Tiene solo unos pocos elementos básicos: objetos (pares nombre-valor entre llaves), arrays (listas entre corchetes), cadenas entre comillas dobles, números, true, false y null. A pesar del nombre, todos los lenguajes habituales pueden leerlo y escribirlo, y por eso se convirtió en la lengua común de las API web. Existen otros estilos que responden a necesidades distintas: GraphQL permite al cliente especificar exactamente qué campos quiere, y gRPC usa un formato binario compacto para llamadas rápidas entre servicios; el Capítulo 6 los compara.
Ejemplo práctico
Ejemplo práctico: llamar a una API del clima
Una app de viajes quiere el pronóstico de mañana para Kigali. El proveedor (aquí un api.example.com inventado) documenta un endpoint (una URL que acepta un tipo concreto de solicitud) y entrega a la app una clave de API.
| 1. Leer el contrato | La documentación dice: GET /v1/forecast con los parámetros de consulta city y days; envía la clave en una cabecera Authorization; las respuestas son JSON; límite de 60 solicitudes por minuto. |
|---|---|
| 2. Enviar la solicitud | La app envía la solicitud HTTP que se muestra abajo, por HTTPS, para que la clave y los datos viajen cifrados. |
| 3. Comprobar el estado | 200 significa que el cuerpo contiene un pronóstico. 401 significa que la clave es incorrecta; 429 significa que hay que ir más despacio; 503 significa que hay que volver a intentarlo más tarde. |
| 4. Analizar el JSON | La app lee days[0].max_c y days[0].rain_chance e ignora los campos que no necesita. |
| 5. Gestionar el fallo | Si no llega ninguna respuesta en, por ejemplo, 3 segundos, la app muestra el último pronóstico guardado en caché en lugar de una pantalla en blanco. |
Cada paso depende del contrato, no de cómo calcula los pronósticos el proveedor. El proveedor puede pasarse mañana a servidores nuevos o a un nuevo modelo meteorológico sin que la app cambie.
El paso 5 es el que olvidan los principiantes: cualquier llamada a través de una red puede ser lenta o fallar, así que quien llama debe decidir qué hacer cuando eso ocurra.
GET /v1/forecast?city=Kigali&days=2 HTTP/1.1
Host: api.example.com
Authorization: Bearer sk_test_4f9a...
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
{
"city": "Kigali",
"units": "metric",
"days": [
{"date": "2026-10-23", "min_c": 16, "max_c": 27, "rain_chance": 0.6},
{"date": "2026-10-24", "min_c": 16, "max_c": 26, "rain_chance": 0.4}
]
}import os
import requests
API_KEY = os.environ["WEATHER_API_KEY"] # never hard-code secrets
resp = requests.get(
"https://api.example.com/v1/forecast",
params={"city": "Kigali", "days": 2},
headers={"Authorization": f"Bearer {API_KEY}"},
timeout=3, # give up after 3 seconds
)
resp.raise_for_status() # raises an error for 4xx and 5xx
tomorrow = resp.json()["days"][0]
print(tomorrow["max_c"], "degrees, rain chance", tomorrow["rain_chance"])¿Quién llama? Claves de API y tokens
La mayoría de las API necesitan saber quién llama, para facturarle, limitarle y decidir qué puede ver. Conviene separar dos ideas desde el principio. La autenticación responde a "¿quién eres?"; la autorización responde a "¿qué tienes permitido hacer?"
Una clave de API es una cadena secreta larga que identifica a la aplicación que llama y se envía con cada solicitud, normalmente en una cabecera. Es sencilla, e identifica a un programa en lugar de a una persona. Un token de acceso es una credencial de corta duración que se emite después de que alguien inicia sesión, a menudo en nombre de un usuario concreto y con permisos concretos ("leer el calendario de este usuario, pero no su correo electrónico"); normalmente se envía como Authorization: Bearer <token>. Los tokens caducan, así que uno robado solo es útil durante un tiempo limitado. Los protocolos estándar que hay detrás, OAuth 2.0 y OpenID Connect, se tratan en identidad y acceso.
Se use lo que se use, las reglas son las mismas: envía las credenciales solo por HTTPS, mantenlas fuera del código fuente y de las apps para dispositivos móviles, de donde cualquiera puede extraerlas, guárdalas en un gestor de secretos o en la configuración del entorno, y asegúrate de poder revocarlas y sustituirlas rápidamente.
Webhooks: la API te devuelve la llamada
A veces el cliente necesita saber cuándo ocurre algo en el lado del proveedor: un pago se completa, se entrega un paquete, se firma un documento. El cliente podría sondear (polling), preguntando "¿ya ha ocurrido?" cada pocos segundos, lo que desperdicia solicitudes y aun así se entera tarde. Un webhook invierte el sentido: el cliente registra una URL propia y el proveedor envía un HTTP POST a esa URL cuando se produce el evento. El término lo acuñó Jeff Lindsay en 2007.
Los webhooks traen responsabilidades. El endpoint receptor está en la internet pública, así que debe comprobar que cada llamada procede realmente del proveedor, normalmente verificando una firma criptográfica en una cabecera. Los proveedores reintentan cuando el receptor no responde, así que el mismo evento puede llegar dos veces y el receptor debe reconocer los duplicados (procesar un duplicado no debe hacer que el pedido se envíe dos veces). Y los eventos pueden llegar desordenados.
Esperar una respuesta, o no: síncrono y asíncrono
Todo lo visto hasta ahora ha sido síncrono: quien llama envía una solicitud y espera la respuesta antes de continuar, como en una llamada telefónica. Es fácil de razonar, y es la opción correcta cuando quien llama necesita de verdad la respuesta en ese momento, como "¿se ha aprobado este pago con tarjeta?". Su punto débil es que quien llama solo está tan disponible y es tan rápido como todo aquello de lo que está esperando.
La alternativa es la mensajería asíncrona, más parecida a dejar una carta en un buzón. El emisor pone un mensaje en una cola de mensajes y sigue con lo suyo. El receptor toma los mensajes de la cola cuando está listo. Si el receptor va lento o está caído durante una hora, los mensajes esperan en lugar de fallar. Cuando la tienda confirma un pedido, enviar el correo electrónico de confirmación no tiene por qué bloquear la pantalla del cliente; un mensaje que diga OrderPlaced puede ir a una cola para que el servicio de correo lo gestione un momento después.
La asincronía no es gratis. El emisor no sabe de inmediato si el trabajo ha tenido éxito, el sistema se vuelve más difícil de rastrear y de probar, y los mensajes pueden entregarse más de una vez. Decidir qué interacciones deben ser síncronas y cuáles asíncronas es una de las decisiones centrales de los sistemas distribuidos, tratada a fondo en comunicación y API y en colas y back pressure.
Guía de decisión
Guía de decisión: ¿llamar ahora o enviar un mensaje?
Una guía inicial para una interacción entre dos partes de un sistema. El Capítulo 6 la afina.
- ¿Necesita quien llama el resultado antes de poder responder a su propio usuario (por ejemplo, si se ha aprobado la tarjeta)?SíUsa una llamada síncrona, con un timeout y un plan para cuando el otro lado vaya lento o esté caído.NoPasa a la siguiente pregunta.
- ¿Puede hacerse el trabajo unos segundos o minutos más tarde sin que nadie lo note (enviar un correo electrónico, actualizar un informe)?SíEnvía un mensaje asíncrono a través de una cola, para que un receptor lento o caído no bloquee a quien llama.NoPasa a la siguiente pregunta.
- ¿Es lento el trabajo (de segundos a horas), como generar una exportación grande?SíAcepta la solicitud de inmediato (por ejemplo, con 202 Accepted), haz el trabajo desde una cola y avisa al cliente cuando esté terminado mediante un webhook o una URL de estado que pueda consultar.NoUna llamada síncrona sencilla suele bastar; mantenla rápida y fija un timeout.
Convivir con las API de otros: SDK, versiones y límites
Muchos proveedores publican un SDK (kit de desarrollo de software): una biblioteca para cada lenguaje popular que envuelve las llamadas HTTP en funciones normales, de modo que un desarrollador escribe client.refunds.create(payment_id) en lugar de construir las solicitudes a mano. Los SDK ahorran tiempo y se ocupan de detalles como los reintentos y las firmas, pero son otra dependencia que hay que mantener al día.
Una vez que una API tiene usuarios, cambiarla se vuelve delicado. Añadir un campo opcional nuevo a una respuesta suele ser seguro. Cambiar el nombre de un campo, eliminarlo, cambiar su tipo o su significado, o hacer obligatoria una entrada opcional es un cambio incompatible (breaking change): todos los clientes que dependían del comportamiento anterior se rompen, a menudo en producción y a menudo para un proveedor que no puede ver ni actualizar esos clientes (piensa en las apps para dispositivos móviles que los usuarios nunca actualizan). Por eso los proveedores asignan una versión a sus API, por ejemplo /v1/ y /v2/ en la URL o una cabecera de versión, mantienen la versión anterior en funcionamiento durante un periodo publicado y anuncian las obsolescencias (avisos de que una función se va a retirar) con mucha antelación. La observación de Hyrum Wright, conocida como ley de Hyrum, añade una advertencia: con suficientes usuarios, alguien dependerá de cada comportamiento observable de una API, incluidos los que la documentación nunca prometió.
Los proveedores también se protegen con un límite de tasa: un tope como 100 solicitudes por minuto y por clave. Las solicitudes que superan el límite se rechazan con el estado 429 Too Many Requests, a menudo con una cabecera Retry-After que indica cuándo volver a intentarlo. Los clientes deben respetarlo, repartir sus solicitudes, guardar en caché las respuestas que no cambian a menudo y retroceder (back off) cuando se les indique.
Usar API de terceros: construir o comprar
Las aplicaciones modernas se ensamblan tanto como se escriben. Una app de reparto de comida podría usar la API de un proveedor de pagos para cobrar con tarjeta, una API de mapas para direcciones y rutas, una API de correo electrónico o SMS para los recibos y un servicio de notificaciones push para avisar de que "tu repartidor está cerca". Cada una ahorra meses de trabajo especializado y aporta una experiencia (seguridad de tarjetas, datos cartográficos globales, entregabilidad del correo electrónico) que pocos equipos podrían igualar.
Cada una aporta también una dependencia que el equipo no controla: las caídas del proveedor se convierten en tus caídas, sus cambios de precio se convierten en tus costos, su tratamiento de los datos pasa a formar parte de tu historia de cumplimiento normativo, y abandonarlo puede obligar a reescribir código. Los profesionales gestionan esto de forma deliberada. Aíslan cada proveedor detrás de una pequeña interfaz propia, de modo que solo una parte del código conozca la API del proveedor; fijan timeouts y deciden qué ocurre cuando el proveedor está caído; vigilan la página de estado y el registro de cambios del proveedor; y anotan lo que costaría cambiar de proveedor.
Por qué esto importa para la arquitectura
La arquitectura trata en gran medida de las partes de un sistema y de los contratos entre ellas, y las API son esos contratos hechos realidad. Una API que es fácil de usar correctamente y difícil de romper permite a los equipos trabajar en paralelo y cambiar libremente su funcionamiento interno; una API con fugas o inestable acopla a todos con todos. La elección entre llamadas síncronas y mensajes asíncronos determina cómo se propagan los fallos. El Capítulo 3 explica los principios de las buenas interfaces (ocultación de información y abstracción), y el Capítulo 6 muestra cómo las decisiones sobre API y mensajería hacen triunfar o fracasar a los sistemas distribuidos.
Comprueba lo que has entendido
En la analogía del restaurante, ¿qué corresponde a la API y qué a la implementación?
La carta (y la forma en que el camarero toma los pedidos) es la API: la lista acordada de lo que se puede pedir y de lo que se devuelve. La cocina es la implementación, libre para cambiar siempre que se cumplan las promesas de la carta.
¿Cuál es la diferencia entre una respuesta 404 y una 503, y cuál merece la pena reintentar más tarde?
404 Not Found dice que el recurso solicitado no existe, un problema del lado del cliente que reintentar no resolverá. 503 Service Unavailable dice que el servidor no puede responder temporalmente, así que reintentar tras una espera puede tener éxito.
¿Por qué el receptor de un webhook debe estar preparado para recibir el mismo evento dos veces?
Los proveedores reintentan cuando no reciben a tiempo una respuesta de éxito, aunque la primera entrega se haya procesado en realidad, así que los duplicados son normales. El receptor debe reconocer un evento que ya ha gestionado y no volver a actuar sobre él.
¿Añadir un campo opcional nuevo a una respuesta JSON es normalmente un cambio incompatible?
Normalmente no, porque los clientes bien hechos ignoran los campos que no reconocen. Eliminar un campo o cambiarle el nombre, o cambiar su tipo, sí es un cambio incompatible.
Fuentes y lecturas recomendadas
¿Tienes una pregunta sobre esta sección? ArchitectBot, el asistente de estudio con IA del curso, responde primero a partir del curso.
Pregunta: “¿Cuándo debe una parte de mi sistema llamar a otra con una solicitud síncrona a una API, y cuándo debe enviarle en su lugar un mensaje a través de una cola?”