Prepared Docs

Prepared Docs

⌘K

    Loading navigation…

User

  1. Working With Data
  2. Axonmundi
  3. Websockets

Real-time data and WebSockets

Architecture, protocol contracts, and integration requirements for GraphQL subscriptions and live data through Mundi

This page outlines the architecture, protocol contracts, and integration requirements for streaming real-time data through the AxonMundi router (Mundi). It is intended for frontend engineers consuming live data and backend engineers evaluating or implementing subgraphs for event-driven data sources.

Architecture and topology

The Cosmo Router is a federated GraphQL gateway. It does not terminate arbitrary third-party WebSockets, proprietary socket streams, or raw message protocols directly into the graph.

To ingest live data from an upstream push stream (such as a vendor WebSocket, event stream, or message broker), you must introduce a subgraph service that acts as a protocol bridge and state manager. That service connects to the upstream source, reconstructs and caches state, and exposes standard GraphQL Subscription fields. Mundi then proxies client subscription operations to the subgraph.

A client establishes a single WebSocket connection to Mundi for subscriptions. When an upstream event occurs, the subgraph processes the event, emits the corresponding GraphQL payload, and Mundi delivers it over the active client subscription.

Current environment support

Understanding environment gating is critical before planning live data features:

  • Live-dev: Prepared911 subscriptions through Mundi are active. The router proxies subscription operations directly to Prepared911's AnyCable backend. See the Prepared911 subscriptions contract.
  • Staging and Production: Subscriptions are currently blocked at the router level via chart configuration (security.block_subscriptions.enabled: true). They will remain blocked until live delivery for additional subgraphs is formally approved and hardened.
  • New Subgraphs: No new or third-party subgraph currently delivers live data through Mundi. Any proposed real-time path must be designed, validated, and approved as tracked in the AxonMundi deferred-work register.

Protocol and authentication contract

Subprotocols

  • Client-to-Router: Mundi supports graphql-transport-ws (the modern standard protocol used by Apollo Client's GraphQLWsLink) and legacy graphql-ws. Prepared911 clients standardize on graphql-transport-ws.
  • Router-to-Subgraph: Subgraph WebSocket protocols are configured per subgraph during registration in the registry or local router configuration.

Authentication

Browsers cannot attach custom HTTP headers (such as Authorization) to the initial HTTP Upgrade request during a WebSocket handshake. Consequently, client authentication credentials must be sent inside the connection_init payload immediately after the socket opens:

The router extracts this payload and forwards it upstream to the subgraph's connection context.

Security requirements:

  • Never include credentials or tokens in WebSocket URL query parameters.
  • Never pass tokens in GraphQL operation variables or payloads.
  • Ensure authentication payloads are redacted from application logs.

Router reloads and connection lifecycle

When Mundi reloads its execution configuration (for instance, following a newly published subgraph composition), all active client WebSocket subscriptions are terminated. Client implementations must treat WebSocket disconnections as normal operational events and implement automatic reconnection with exponential backoff and randomized jitter.

Architectural constraints and failure modes

When designing a subgraph that interfaces with live data, take the following constraints into account:

  1. Cosmo Connect gRPC adapters do not support subscriptions. Cosmo Connect (both standalone gRPC services and router plugins) currently supports only queries and mutations. Upstream gRPC streaming and subscription support is not implemented. A Connect schema must not define a Subscription type or @edfs__* directives.
  2. Do not place stateful WebSockets in stateless adapters. Stateless service replicas scale and restart dynamically. Placing a persistent upstream WebSocket connection inside a stateless container leads to connection duplication, uncoordinated reconnect storms, state fragmentation, and memory leaks. Upstream connection lifecycle, reconnect backoff, state reconstruction, and deduplication must belong to a dedicated stateful service.
  3. Registry composition does not validate delivery. A successful schema check or composition in Cosmo Studio confirms only that the GraphQL schema is syntactically and structurally valid. It provides no guarantee that network connectivity, subprotocol negotiation, or event delivery works at runtime.
  4. Header and authorization forwarding boundaries. Mundi currently forwards the incoming Authorization header to subgraphs. Before introducing a non-Prepared or third-party subgraph, authorization forwarding must be scoped per subgraph in the router configuration to prevent inadvertent credential leakage.

Integration workflow for new live data sources

Follow this sequence when bringing an upstream push-based source into the graph:

  1. Evaluate query snapshotting vs. subscription: Determine whether real-time streaming is strictly necessary. If update intervals of several seconds are acceptable, implement a snapshot query with an updatedAt timestamp or version cursor, allowing clients to poll. Polling avoids persistent connection management overhead and fits existing HTTP infrastructure.
  2. Build the stateful bridge service: If streaming is required, implement a stateful service (for example, in Go using gqlgen) that owns the upstream connection, handles jittered reconnects, maintains state in a bounded cache, and exposes standard GraphQL subscriptions.
  3. Pair subscriptions with snapshot queries: Every subscription feature must have a corresponding query to retrieve the initial state. Clients fetch the baseline state on mount and subsequently apply subscription events as deltas.
  4. Configure router policy and permissions: Coordinate with the AxonMundi platform team to configure per-subgraph routing URLs, WebSocket subprotocols, and header forwarding policies, and to approve subscription enablement for the target environment.
  5. Verify resilience and tenant isolation: Validate the integration using automated verification tests that confirm:
    • Successful reconnect behavior after upstream drops and router reloads.
    • Message delivery ordering and deduplication.
    • Strict tenant isolation (verifying that events for Tenant A cannot be delivered to Tenant B). Reference just subscription-isolation-smoke in AxonMundi for the baseline pattern.

Alternative: Event-driven federation (Cosmo Streams / EDFS)

Cosmo Streams allows the router to subscribe directly to event brokers such as Kafka, NATS, or Redis, routing incoming topics directly to client GraphQL subscriptions without custom WebSocket subgraphs.

In this architecture, the brokers serve as the transport between your backend and the router; browser clients still connect to Mundi via standard GraphQL subscriptions. While architecturally clean, Cosmo Streams is currently unproven in this deployment, requires broker infrastructure we do not currently operate for this purpose, and remains a future architectural spike rather than an active integration path.

Frontend client implementation guidelines

When consuming subscriptions in frontend applications:

  • Use typed hooks: Use useSubscription alongside useQuery from @apollo/client, matching the patterns described in the GraphQL operations guide.
  • Reconciliation pattern:
    1. Execute a query to seed initial component state.
    2. Open the subscription to receive incremental deltas or invalidation signals.
    3. If the subscription disconnects and reconnects, re-execute the snapshot query to reconcile state that may have changed during the disconnected window.
  • Fail gracefully: If a subscription fails or is terminated, retain and display the last known valid state with an appropriate freshness indicator rather than unmounting UI components or crashing the view.

References and runbooks

  • Real-time and WebSocket upstreams: technical constraints and boundaries for subgraph authors.
  • Prepared911 subscriptions through Mundi: working client protocol, authentication payloads, and smoke testing.
  • Live delivery for new subgraphs: tracking open platform work for multi-subgraph real-time delivery.

Previous

AxonMundi / Registry and schema workflow

Next

Testing strategy / Testing Principles

On this page

Architecture and topology
Current environment support
Protocol and authentication contract
Subprotocols
Authentication
Router reloads and connection lifecycle
Architectural constraints and failure modes
Integration workflow for new live data sources
Alternative: Event-driven federation (Cosmo Streams / EDFS)
Frontend client implementation guidelines
References and runbooks