CAPÍTULO 0.7 · PARTE 0

Cómo se comunican dos programas

Mensajes, roles, estados y límites al comunicar una aplicación de fotografía con un servicio.

Nivel N0–N1 · Estado published

Cómo se comunican dos programas

Mara abre una aplicación de fotografía y ve que una imagen figura como «subiendo». Unos segundos después aparece «lista». Parece una transición sencilla, pero la pantalla comprime varias acciones: un programa preparó una petición, otro recibió o no recibió un mensaje, alguna parte interpretó su formato, hubo una respuesta y la interfaz tradujo esa respuesta a una etiqueta. Para comprender la interacción hay que separar lo observado de lo inferido.

Este capítulo construye un mapa mínimo para seguir mensajes entre dos programas. Usaremos emisor, receptor, formato, protocolo, estado, petición y respuesta. También estudiaremos situaciones que suelen producir conclusiones falsas: mensajes que llegan tarde, respuestas que no llegan, reintentos que repiten una operación y resultados observados en un orden distinto. Todavía no necesitamos estudiar TCP, UDP, colas ni consistencia distribuida. Necesitamos aprender a formular la pregunta correcta antes de abrir esas capas.

El objetivo no es memorizar una secuencia universal. Cada protocolo puede definir interacciones diferentes. El objetivo es poder reconstruir una interacción concreta: qué programa produjo qué mensaje, bajo qué reglas, qué programa lo interpretó, qué respuesta generó y qué cambio permite sostener la evidencia.

Figura 0.7-01 · ¿Qué viaja entre programas?

Desliza horizontalmente para leer el diagrama a tamaño completo.

Secuencia con aplicación C y servicio S: Q viaja al servicio y refiere a X; R vuelve a C con una representación del estado de X.

El caso conductor: consultar una fotografía

La aplicación conserva una miniatura local y conoce un identificador de la fotografía. Para averiguar qué informa el servicio remoto, crea una petición de consulta. La petición puede expresar algo como «dame el estado del recurso identificado por X». El servicio interpreta la solicitud y devuelve una respuesta que contiene un resultado y, quizá, una representación del estado: recibida, procesando, disponible o rechazada.

La petición no es la fotografía. El identificador no es la fotografía. La respuesta tampoco es el estado interno completo del servicio. Son representaciones construidas para una interacción. RFC 9110 distingue recursos y representaciones: una representación comunica información sobre el estado de un recurso, pero no se identifica sin más con el recurso (RFC 9110, §§3.1–3.2). Esta diferencia evita concluir que ver una miniatura o recibir un campo available equivale a inspeccionar cada copia almacenada.

El caso incluye dos preguntas distintas. «¿Qué dice el servicio ahora sobre X?» puede resolverse con una consulta bien definida. «¿En qué lugares persiste cada copia de X?» requiere otras evidencias y pertenecía al capítulo anterior. Mantener separadas ambas preguntas evita cargar un mensaje con garantías que nunca expresó.

Emisor, receptor y dirección

Llamaremos emisor al programa que produce el mensaje considerado y receptor al programa que lo recibe para interpretarlo. Estos nombres dependen del mensaje, no de una identidad permanente. En la petición, la aplicación es emisora y el servicio es receptor. En la respuesta, el servicio emite y la aplicación recibe. Si el servicio consulta después otro componente, será cliente en esa nueva interacción aunque haya sido servidor frente a la aplicación.

RFC 9110 define cliente y servidor como roles relativos a una conexión o intercambio HTTP: el cliente inicia una petición y el servidor la acepta para responder (RFC 9110, §3.3). Por eso «cliente» no significa persona, teléfono o programa débil, y «servidor» no significa necesariamente una máquina física única. Un mismo proceso puede participar en roles distintos, y una interfaz visible puede ser sólo una parte del programa cliente.

Nombrar dirección también previene atribuciones rápidas. La aplicación puede mostrar una frase generada localmente antes de recibir confirmación remota. En ese caso, la interfaz es productora de la etiqueta visible aunque el servicio sea la autoridad prevista para el estado remoto. La frase «el servidor dijo disponible» necesita evidencia de una respuesta atribuible al servidor, no sólo un color verde en la pantalla.

Mensaje, contenido y significado

Un mensaje es una unidad de comunicación reconocible bajo las reglas de un protocolo. Puede contener información de control, campos y contenido. En la abstracción de mensajes HTTP aparecen datos de control, campos, contenido y datos asociados a la versión o transporte (RFC 9110, §6). No necesitamos conocer todavía su codificación exacta; sí debemos distinguir las partes y su función.

El contenido transporta una representación o datos para la operación, pero el significado proviene del protocolo y del contexto. El valor 202 aislado es un número. Interpretado como código de estado HTTP tiene una semántica definida. El texto ready puede ser un valor documentado por la aplicación o una palabra sin contrato. Dos mensajes con bytes diferentes pueden expresar el mismo estado; dos mensajes con la misma palabra pueden tener sentidos distintos en protocolos diferentes.

Un mensaje tampoco es el acontecimiento que describe. «La fotografía está disponible» puede ser contenido de una respuesta. La disponibilidad efectiva es una propiedad situada del servicio y el recurso. Para relacionarlas debemos conocer quién produjo la respuesta, qué consulta responde, en qué momento y qué significa ese campo. Esta disciplina es especialmente importante en seguridad: datos con apariencia familiar no adquieren autoridad por su formato.

Formato y protocolo no son lo mismo

El formato organiza la representación: qué partes existen, cómo se nombran y cómo se delimitan. Un receptor necesita poder reconocer esas partes para interpretarlas. Los campos HTTP, por ejemplo, tienen nombres y valores cuya semántica depende de la especificación del campo (RFC 9110, §5). Un formato puede indicar que existe un campo state; no decide por sí mismo quién está autorizado a enviarlo ni qué transición interna representa.

El protocolo añade reglas de interacción. Define roles, tipos de mensajes, métodos, respuestas y condiciones de interpretación. También puede dejar decisiones a la aplicación. Dos programas pueden intercambiar texto perfectamente legible y aun así no comunicarse correctamente si discrepan sobre el significado, el orden permitido o el recurso referido.

Imaginemos que el servicio espera photo_id y la aplicación envía photo. El mensaje podría estar bien formado como objeto, pero no cumplir el contrato esperado. Al contrario, un mensaje puede usar todos los nombres correctos y transportar un identificador de otro recurso. La corrección sintáctica no demuestra corrección semántica. Esta separación será útil después para comprender por qué validación, autenticación y autorización responden preguntas diferentes.

Figura 0.7-02 · ¿Cómo se separan petición y respuesta?

Desliza horizontalmente para leer el diagrama a tamaño completo.

Comparación: un mensaje dividido en campos y contenido frente a reglas que asignan significado a método, objetivo y respuesta.

Petición: intención, no resultado

Una petición expresa la intención del cliente dentro del protocolo. En HTTP, el método es el principal portador de la semántica de la petición; indica para qué se realiza y qué espera el cliente (RFC 9110, §§9–9.1). La petición también identifica un objetivo y puede incluir campos o contenido. Cada parte contribuye a interpretarla.

Que la aplicación construya una petición demuestra un cambio local. Que la entregue a una biblioteca de comunicación demuestra otro. Que el servicio la reciba, analice y aplique son afirmaciones posteriores. Decir «se pidió subir la foto» es correcto si observamos la acción local; decir «el servicio recibió la foto» exige evidencia del receptor o una respuesta con el alcance adecuado.

La intención tampoco garantiza el efecto. Un método puede pedir consultar, crear, sustituir o eliminar, pero el servidor puede rechazar la solicitud, aplicar una regla condicional o producir un error. La semántica del método ayuda a interpretar lo solicitado; la respuesta y el estado observado ayudan a interpretar lo ocurrido.

Respuesta: resultado situado

Una respuesta se relaciona con una petición y comunica cómo fue atendida según el protocolo. En HTTP, el código de estado describe el resultado de intentar comprender y satisfacer la petición (RFC 9110, §15). El contenido puede añadir una representación o una explicación. Para interpretarla hay que conservar la petición correspondiente.

Una respuesta 200 OK significa que la petición fue satisfecha con éxito según la semántica aplicable; el contenido depende del método (RFC 9110, §15.3.1). No significa universalmente «guardado para siempre», «visto por una persona» ni «replicado en todos los componentes». En una consulta de estado puede significar que la consulta fue atendida y devolvió una representación válida. La propiedad de persistencia tendría que provenir del contrato de la aplicación y de evidencia adicional.

La respuesta también puede proceder de una capa intermedia autorizada por el protocolo o de una caché. Este capítulo no desarrolla intermediarios, pero conserva una regla: identifica el productor observable y no atribuyas más alcance del que la respuesta declara. «Recibí una respuesta satisfactoria para la consulta Q» es más fuerte y verificable que «todo salió bien».

Figura 0.7-03 · ¿Qué estado de la foto se observa?

Desliza horizontalmente para leer el diagrama a tamaño completo.

Q recibe 200 y una representación disponible; tres ramas separadas marcan como no demostradas persistencia, lectura humana y todas las copias.

Estados locales y remotos

Estado es información relevante sobre una entidad en un momento. La aplicación puede mantener pendiente, enviando o respuesta recibida. El servicio puede mantener recurso desconocido, procesando o disponible. Las palabras pueden parecer equivalentes, pero pertenecen a productores y fronteras diferentes.

Cuando Mara pulsa «subir», la interfaz puede cambiar inmediatamente a subiendo. Ese cambio permite afirmar que el cliente inició su flujo local. Si después recibe una respuesta que representa procesando, puede actualizar su vista. Ninguna de esas etiquetas describe automáticamente todos los estados internos del servicio. La pantalla resume lo que el cliente conoce o decide mostrar.

Para evitar confusión, podemos registrar cada transición como una tupla: entidad, estado anterior, evento observado, estado posterior y productor de la evidencia. Por ejemplo: «cliente C: preparado → petición emitida, según su registro local». O bien: «servicio S: consulta del recurso X → representación procesando, según respuesta R a las 10:32». Si no observamos el estado remoto, lo dejamos como desconocido.

Esta notación no pretende modelar toda la implementación. Sirve para impedir que una sola línea de progreso se convierta en historia universal. Un cliente puede estar esperando mientras el servicio ya terminó; puede mostrar lista desde una respuesta anterior; puede recibir una respuesta válida para otro identificador. La pregunta siempre vuelve a entidad, mensaje y momento.

Qué significa «entregado»

La palabra entrega necesita un destino. Una aplicación puede entregar datos a su propia biblioteca; una capa de comunicación puede aceptar el mensaje; el programa receptor puede recibirlo; el servidor puede aceptar la operación; la aplicación remota puede cambiar estado. Cada límite produce evidencia distinta.

Una respuesta suele aportar evidencia más fuerte que el simple envío local: algo capaz de responder interpretó una petición correlacionada. Aun así, su alcance depende de la semántica. Una respuesta a una consulta prueba que esa consulta obtuvo un resultado; no prueba necesariamente que otro mensaje anterior se almacenó de forma durable. Una confirmación de aceptación puede significar que el trabajo empezará después, no que terminó.

Por eso una afirmación debe completar la frase: «entregado a…». Si sólo existe un registro local, decimos «el cliente entregó la petición a su componente de comunicación». Si existe una respuesta del servicio, decimos «el servicio respondió a la petición Q». Si el contrato declara y demuestra un cambio remoto, describimos ese cambio. No saltamos de una frontera a otra por comodidad verbal.

Tiempo, espera y timeout

El cliente no puede esperar indefinidamente cada respuesta. Define una condición temporal: si no recibe una respuesta correlacionada antes del límite, genera un timeout. El hecho observado es local: la espera terminó sin la respuesta esperada. Las causas siguen abiertas.

La petición pudo no salir, perderse antes del receptor, llegar y quedar en proceso, producir una respuesta que llegó tarde o encontrar un fallo distinto. Este capítulo no selecciona una capa de red ni enseña sus mecanismos; conserva hipótesis que predicen observaciones diferentes. Un registro del cliente puede mostrar emisión; un registro del servicio puede mostrar recepción; una respuesta posterior puede mostrar que hubo procesamiento.

Un timeout tampoco es una respuesta del servidor. No debe interpretarse como un código remoto ni como denegación. Es una decisión del cliente o de un componente que esperaba. Su configuración afecta qué se observa: un límite demasiado corto puede producir timeouts aunque el servicio responda dentro de su comportamiento previsto; uno muy largo puede degradar la experiencia. Determinar el valor correcto pertenece al diseño del sistema, no a una regla universal.

Figura 0.7-04 · ¿Qué puede significar una espera agotada?

Desliza horizontalmente para leer el diagrama a tamaño completo.

Tres secuencias producen timeout local: Q no llega; Q se procesa pero R no llega; Q se procesa y R llega tarde.

Reintento e incertidumbre sobre el efecto

Tras un timeout, repetir parece razonable: quizá la primera petición nunca llegó. El problema es que el cliente no sabe eso sólo por la ausencia de respuesta. Si el servicio aplicó la primera operación y la respuesta se perdió, el reintento puede producir una segunda aplicación.

RFC 9110 llama idempotente a un método cuando el efecto intencional en el servidor de varias peticiones idénticas es el mismo que el de una sola. La propiedad pertenece a la semántica solicitada, no a que los mensajes sean idénticos ni a que las respuestas coincidan (RFC 9110, §9.2.2). Incluso para métodos idempotentes pueden existir efectos secundarios de registro o respuestas distintas.

Consultar el estado de X suele formularse como una operación sin intención de cambiarlo. Repetir esa consulta puede ser compatible con su semántica. Crear una compra, enviar una notificación o registrar una fotografía puede requerir una regla adicional de la aplicación para distinguir intentos. No desarrollaremos aquí claves de idempotencia ni deduplicación. Basta reconocer la pregunta: ¿qué propiedad permite repetir sin convertir incertidumbre en efectos acumulados?

El reintento también necesita identidad temporal. La respuesta tardía de la primera petición puede llegar cuando la segunda ya está activa. El cliente debe saber a qué petición corresponde cada respuesta según el protocolo. Si no puede correlacionarlas, la etiqueta final puede atribuir un resultado correcto al intento equivocado.

Orden: tres preguntas diferentes

Cuando hay dos mensajes A y B, podemos preguntar en qué orden los produjo el cliente, en qué orden los recibió el servicio y en qué orden se volvieron observables sus efectos. No son la misma afirmación. Un registro local puede probar A antes que B; una secuencia de respuestas puede mostrar B antes que A; ninguna observación aislada establece por sí sola la causalidad interna.

En el caso de Mara, A consulta el estado y B solicita cambiar un título. Si la interfaz muestra primero la respuesta de B, eso sólo establece el orden de presentación. Para afirmar el orden de recepción necesitaríamos evidencia del receptor. Para afirmar el orden de aplicación necesitaríamos observar o documentar las transiciones correspondientes.

No deduciremos aquí qué garantiza un transporte concreto. Tampoco introduciremos colas. El principio N0–N1 es más básico: cada claim de orden nombra eventos, productor de la evidencia y frontera. «Apareció primero» no equivale a «causó lo segundo». Este hábito evita muchos diagnósticos erróneos cuando más adelante aparezcan concurrencia y sistemas distribuidos.

Duplicación: mensajes, peticiones y efectos

Duplicado también necesita objeto. El cliente puede emitir dos mensajes con el mismo contenido. El servicio puede reconocerlos como dos peticiones. La aplicación puede aplicar un efecto una o dos veces. Una interfaz puede mostrar dos entradas aunque sólo exista un efecto remoto. Llamar duplicado a todo oculta la capa donde surgió.

Supongamos que el cliente emite Q1, agota la espera y emite Q2. Ambas consultan X. Desde el cliente hay dos peticiones. Si el servicio recibe las dos, puede producir dos respuestas. Si la operación es una consulta idempotente, el estado intencional del recurso no se multiplica, aunque las respuestas reflejen momentos diferentes. Si la operación crea un objeto sin una regla de repetición, dos recepciones pueden producir dos efectos.

La evidencia útil conserva identificadores y estados. No basta ver dos notificaciones y afirmar «la red duplicó». Tal vez el cliente reintentó, el servidor emitió eventos distintos o la interfaz repitió una representación. La explicación se decide comparando mensajes, correlación y cambios observados, no escogiendo la causa más familiar.

Figura 0.7-05 · ¿Qué orden y duplicación se observaron?

Desliza horizontalmente para leer el diagrama a tamaño completo.

Cuatro filas muestran Q1 antes de Q2 al emitir, posible recepción doble, un efecto idempotente y R2 presentada antes de R1.

Roles relativos en una cadena

La aplicación de Mara puede hablar con un servicio de fotografías, que a su vez consulta un componente de metadatos. Frente a Mara, el servicio de fotografías actúa como servidor. Frente al componente de metadatos, actúa como cliente. El cambio de rol no implica que haya cambiado de programa ni que una máquina se haya movido.

Este mapa importa porque una respuesta hacia Mara puede depender de otra interacción que ella no observa. Si el componente de metadatos tarda, el servicio puede responder con un estado provisional o con error. La aplicación sólo ve la respuesta que llega a su frontera. No debe inventar qué componente interno falló.

Cliente y servidor tampoco sustituyen identidad y autorización. Que un programa ocupe el rol servidor no demuestra quién lo opera. Que un cliente pueda enviar una petición no demuestra que esté autorizado para la acción. Esas distinciones vienen del capítulo 0.6 y se conservan aquí: rol describe dirección de interacción; principal y permiso describen decisiones de seguridad.

De una interfaz a un claim defendible

La pantalla muestra «lista». Esa observación es real pero estrecha: un cliente presentó una etiqueta. Para afirmar que el servicio informó disponible, necesitamos relacionar la vista con una respuesta. Para afirmar que el recurso puede recuperarse ahora, necesitamos una consulta u operación cuyo resultado cubra esa propiedad. Para afirmar persistencia futura haría falta un contrato y evidencia adicionales.

Una formulación calibrada puede ser: «A las 10:32, el cliente C recibió del servicio S una respuesta satisfactoria a la consulta Q sobre X; la representación indicó disponible». La frase no afirma que todas las copias existen, que una persona vio la imagen ni que el estado durará indefinidamente. Añade sólo lo que nuevas evidencias sostienen.

Cuando la interfaz muestra error, aplicamos la misma disciplina. «La aplicación informó timeout tras cinco segundos» no se convierte en «el servidor rechazó la fotografía». Cuando muestra éxito, «la consulta recibió 200 con representación R» no se convierte en «todo quedó guardado». La calidad del diagnóstico depende de no premiar resultados positivos con menos escepticismo que los negativos.

Figura 0.7-06 · ¿Qué permite afirmar la interfaz?

Desliza horizontalmente para leer el diagrama a tamaño completo.

Escalera desde etiqueta local a registro, respuesta correlacionada y claim sobre S, X y T; persistencia futura queda tras una frontera no cruzada.

Método de reconstrucción

Ante una interacción confusa, sigue este orden:

  1. Nombra los dos programas y asigna roles para el mensaje concreto.
  2. Identifica el recurso u objetivo y separa su referencia de su representación.
  3. Describe la petición: intención, momento y contenido relevante.
  4. Describe la respuesta correlacionada, si existe, sin ampliar su semántica.
  5. Registra estados locales y remotos como entidades separadas.
  6. Si hubo timeout, conserva hipótesis rivales y señala qué observación las discrimina.
  7. Si hubo reintento, pregunta por idempotencia, correlación y posibles efectos repetidos.
  8. Si importa el orden, especifica orden de emisión, recepción, aplicación o presentación.

El método no exige inspeccionar sistemas ajenos ni convertir el capítulo en laboratorio. Puede aplicarse a documentación, registros autorizados o un diagrama de arquitectura. Su valor es producir una explicación revisable: otra persona puede señalar exactamente qué evidencia falta o qué relación fue inferida.

Transferencia: un editor de documentos

Un editor guarda un cambio y muestra «sincronizado». El recurso ya no es una fotografía, sino una versión del documento. El cliente emite una petición; el servicio responde; la interfaz produce una etiqueta. Un timeout deja abierta la posibilidad de que el cambio se haya aplicado. Reintentar una consulta de estado no tiene el mismo riesgo que volver a crear una versión.

El mapa se conserva, pero los estados y la semántica cambian. Para afirmar «el documento remoto contiene el párrafo P» hace falta una respuesta o lectura que represente esa versión, no sólo el indicador local. Para afirmar «nadie más puede editarlo» haría falta autorización, fuera de la comunicación básica. Transferir bien el modelo significa conservar sus preguntas y volver a obtener las respuestas del nuevo contrato.

Límites del capítulo

No hemos explicado cómo viajan bytes por una red, cómo un transporte ordena datos, cómo se codifica un objeto, cómo funciona una cola ni cómo varios nodos acuerdan estado. Esos mecanismos merecen capítulos propios. Tampoco hemos presentado HTTP como el único protocolo posible: lo usamos como fuente primaria accesible para roles, mensajes, métodos y respuestas.

El modelo sigue siendo riguroso dentro de su dominio. Permite separar mensaje de efecto, formato de protocolo, cliente de persona, servidor de máquina, timeout de rechazo y reintento de entrega garantizada. Esas distinciones son prerrequisitos para estudiar redes y web sin confundir capas.

Fuentes principales

  1. RFC 9110, §§3, 5, 6, 9 y 15 — recursos, representaciones, roles, campos, mensajes, métodos y respuestas.
  2. RFC 9293, §§1 y 3 — referencia limitada para distinguir transporte de semántica de aplicación; sus mecanismos se dejan fuera de alcance.

Comprobación

Mara ve «error de subida» después de cinco segundos y pulsa reintentar. Poco después aparecen «lista» y una segunda notificación. Reconstruye al menos dos historias compatibles con esas observaciones. En cada una identifica petición inicial, timeout, segunda petición, respuesta o respuesta tardía y estado que sigue desconocido. Después escribe el claim más fuerte que podría sostenerse sólo desde la interfaz y nombra una evidencia del receptor que permitiría distinguir las historias.