¿Qué es la idempotencia?

En informática, la idempotencia es una propiedad de una operación en la que aplicarla varias veces tiene el mismo efecto final que aplicarla solo una vez. Si envías la misma solicitud a un servidor cinco veces, un sistema idempotente garantiza que el resultado en el servidor no cambie después del primer intento exitoso.

Además de garantizar el mismo resultado, una característica clave de las operaciones idempotentes es que no producen efectos secundarios con llamadas adicionales. Este es un requisito fundamental para crear sistemas distribuidos resilientes en los que las interrupciones intermitentes de la red o los tiempos de espera pueden hacer que un cliente envíe el mismo mensaje más de una vez.

Analogía: Piensa en el botón "subir" de un ascensor. Si lo presionas una vez, el ascensor se llama a tu piso. Si lo presionas diez veces más mientras esperas, el resultado es el mismo: un ascensor llega a tu piso. Presionar el botón varias veces no hace que aparezcan diez ascensores separados. Por el contrario, agregar un artículo a un carrito de compras digital no suele ser idempotente. Si haces clic en el botón "Agregar al carrito" cinco veces, es probable que termines con cinco ejemplares de ese artículo en tu cesta.

Beneficios clave de los sistemas idempotentes

Vuelve a intentar las solicitudes de forma segura después de un tiempo de espera o una caída de la conexión sin temor a duplicar acciones (como cobrar dos veces a una tarjeta de crédito).

Los usuarios no necesitan un seguimiento de estado complejo para saber si una solicitud anterior tuvo éxito; simplemente pueden "reintentar hasta que tenga éxito".

Los sistemas distribuidos pueden recuperarse de fallas reproduciendo registros o reenviando mensajes perdidos sin dañar los datos.

Métodos HTTP idempotentes versus no idempotentes

El estándar REST define cómo deben comportarse los diferentes tipos de solicitudes web. Algunos métodos HTTP son naturalmente "seguros" o idempotentes por diseño, lo que significa que la especificación espera que se comporten de manera predecible incluso cuando se repiten. Otros están diseñados para crear datos nuevos y requieren un cuidado adicional para que sean seguros en los reintentos.

Métodos idempotentes (GET, PUT, DELETE)

Según RFC 9110, varios métodos estándar son inherentemente idempotentes. Repetir estas acciones no debería cambiar el estado del servidor más allá de la solicitud inicial.

  • GET: Este método recupera datos. Como no cambia nada en el servidor, puedes llamarlo un millón de veces y el recurso sigue siendo el mismo.
  • PUT: Este método reemplaza un recurso por completo. Si actualizas el correo electrónico de un usuario a "usuario@example.com" tres veces, el estado final sigue siendo que el correo electrónico es "usuario@example.com".
  • DELETE: Esto quita un recurso. Si borras "Pedido núm. 123" y, luego, intentas borrarlo de nuevo, el pedido permanece borrado. El resultado (el pedido desaparece) sigue siendo el mismo.

Métodos no idempotentes (POST, PATCH)

Algunos métodos no son idempotentes porque su trabajo principal es cambiar los datos de una manera que cree algo nuevo o modifique una parte de un registro existente.

  • POST: Los desarrolladores usan POST para crear recursos nuevos. Sin la lógica de idempotencia, enviar la misma solicitud POST dos veces (como "Enviar pago") normalmente daría como resultado dos registros separados y dos cargos al cliente.
  • PATCH: Este método aplica actualizaciones parciales. Si bien se puede hacer idempotente, a menudo no lo es de forma predeterminada porque repetir un cambio relativo (como "agregar 5 al saldo") daría como resultado un valor final diferente cada vez que se llama.

Cómo implementar una API idempotente

  1. Generar una clave única: El cliente crea una cadena única (como un UUID) y la incluye en un encabezado HTTP personalizado.
  2. Interceptar y validar: El servidor comprueba un almacén de datos de alta velocidad como Memorystore para ver si esa clave se procesó recientemente.
  3. Manejar el estado: Si la clave es nueva, procesa la solicitud y guarda el resultado. Si es un duplicado, devuelve el resultado almacenado de inmediato sin volver a ejecutar la lógica empresarial.

Casos de uso comunes para la idempotencia

La idempotencia suele ser necesaria en los sistemas que creamos. En algunos casos, se maneja por nosotros. En otros, los desarrolladores debemos tomar medidas para que esto suceda.

El ejemplo más famoso es el problema del "doble cargo". Si el navegador de un usuario se congela mientras paga un vuelo, es posible que haga clic en "Pagar" de nuevo. Una API de pago que usa una clave de idempotencia garantiza que el segundo clic se reconozca como un reintento. Esto protege la cuenta bancaria del cliente y reduce el costo operativo de administrar los reembolsos por transacciones duplicadas.

  • Acción obligatoria para el desarrollador: Debes implementar una clave de idempotencia (a menudo un UUID) en tu solicitud a la API para garantizar que el segundo clic se reconozca como un reintento, lo que protegerá la cuenta bancaria del cliente.

Herramientas como Terraform y Ansible dependen de la idempotencia. Cuando ejecutas una secuencia de comandos para "crear un bucket de almacenamiento de 10 GB", la herramienta verifica el estado actual de tu nube.

  • Se maneja por ti: La herramienta de IaC administra la idempotencia; como desarrollador, no necesitas escribir lógica adicional para evitar recursos duplicados.

Las APIs web modernas suelen implementar el encabezado Idempotency-Key (ahora un borrador estandarizado de IETF) para permitir que los desarrolladores creen integraciones más sólidas.

  • Acción obligatoria del desarrollador: Cuando crees el backend, debes implementar la lógica para interceptar estas claves, verificar si hubo intentos anteriores y devolver la respuesta almacenada en caché.

Un "upsert" (actualización o inserción) es una operación de base de datos idempotente clásica. En lugar de un simple "insertar", un upsert dice: "Si este registro existe, actualízalo; si no, créalo".

  • Se maneja por ti: Esta lógica se maneja de forma nativa con el motor de base de datos, lo que garantiza que los registros converjan al estado correcto sin importar cuántas veces se ejecute la secuencia de comandos.

Resuelve tus desafíos más difíciles con Google Cloud

Los clientes nuevos obtienen $300 en créditos gratuitos que pueden usar en Google Cloud.
Habla con un especialista en ventas de Google Cloud para analizar tu desafío único en más detalle.

Crea microservicios confiables en Google Cloud

Google Cloud ofrece varias herramientas que facilitan la implementación de estos patrones para los desarrolladores. La creación en una plataforma administrada reduce la cantidad de código estándar que necesitas escribir para mantener tus datos seguros.

  • Cloud Run: Cuando usas Cloud Run para procesar eventos de Pub/Sub, recuerda que Pub/Sub puede entregar mensajes más de una vez de forma predeterminada. Escribir código idempotente en tus servicios de Cloud Run es un requisito para garantizar que tus agentes de IA o canalizaciones de datos no procesen el mismo evento dos veces.
  • Nota sobre Pub/Sub: Si bien la entrega predeterminada se basa en envío, la entrega "exactamente una vez" está disponible para las suscripciones basadas en extracción. Es útil conocer estos dos tipos para elegir el nivel de complejidad adecuado para tu servicio.

¿Todo listo para crear?

Aprende a implementar servicios resilientes e idempotentes en Cloud Run hoy mismo.

Google Cloud