Skip to main content
Infrahub supports GraphQL subscriptions for real-time event streaming over WebSocket connections. Subscribe to changes and events as they happen.

Subscription Endpoint

Subscriptions use the GraphQL WebSocket protocol:
wss://your-infrahub-instance/graphql

Available Subscriptions

Infrahub currently provides a single subscription type for querying events:

Query Subscription

Subscribe to events with optional filtering and polling interval.
subscription {
  query(
    name: "branch-events"
    interval: 5000
    params: { branches: ["main", "develop"] }
  )
}
name
String
Name identifier for the subscription
interval
Int
Polling interval in milliseconds (default: 1000)
params
GenericScalar
Optional parameters to filter events. Structure depends on the event type being subscribed to.

Event Types

Subscriptions can receive various event types from Infrahub:

Branch Events

Listen for branch-related events:
subscription BranchEvents {
  query(
    name: "branch-lifecycle"
    interval: 2000
    params: {
      branches: ["main"]
    }
  )
}
Event types:
  • BranchCreatedEvent - A new branch was created
  • BranchDeletedEvent - A branch was deleted
  • BranchMergedEvent - A branch was merged
  • BranchRebasedEvent - A branch was rebased

Artifact Events

Subscribe to artifact generation and updates:
subscription ArtifactEvents {
  query(
    name: "artifact-updates"
    interval: 3000
  )
}
Event fields:
  • artifact_definition_id - The artifact definition ID
  • checksum - Current checksum of the artifact
  • checksum_previous - Previous checksum
  • storage_id - Current storage location ID
  • storage_id_previous - Previous storage location
  • branch - Branch where the event occurred
  • event - Event name
  • occurred_at - Timestamp of the event

Repository Events

Monitor Git repository synchronization:
subscription RepositoryEvents {
  query(
    name: "repo-sync"
    interval: 5000
    params: {
      repository_ids: ["repo-123"]
    }
  )
}
Event types:
  • RepositorySyncEvent - Repository sync started or completed
  • RepositoryCommitEvent - New commits detected

Using Subscriptions

With GraphQL Client Libraries

Most GraphQL client libraries support subscriptions over WebSocket:

Apollo Client (JavaScript/TypeScript)

import { WebSocketLink } from '@apollo/client/link/ws';
import { ApolloClient, InMemoryCache } from '@apollo/client';

const wsLink = new WebSocketLink({
  uri: 'wss://your-infrahub-instance/graphql',
  options: {
    reconnect: true,
    connectionParams: {
      authToken: 'your-auth-token',
    },
  },
});

const client = new ApolloClient({
  link: wsLink,
  cache: new InMemoryCache(),
});

const subscription = client.subscribe({
  query: gql`
    subscription {
      query(name: "events", interval: 2000)
    }
  `,
}).subscribe({
  next: (data) => console.log('Event:', data),
  error: (err) => console.error('Error:', err),
});

Python with gql

from gql import Client, gql
from gql.transport.websockets import WebsocketsTransport

transport = WebsocketsTransport(
    url="wss://your-infrahub-instance/graphql",
    headers={"Authorization": "Bearer your-token"}
)

client = Client(transport=transport, fetch_schema_from_transport=True)

subscription = gql("""
    subscription {
        query(name: "branch-events", interval: 5000)
    }
""")

for result in client.subscribe(subscription):
    print(f"Event received: {result}")

WebSocket Protocol

Subscriptions follow the graphql-ws protocol:
  1. Connection Init: Send authentication
  2. Subscribe: Send subscription query
  3. Next: Receive events as they occur
  4. Complete: Close subscription

Event Structure

All events implement the EventNodeInterface:
id
String!
Unique event ID
event
String!
Event type name
branch
String
Branch where the event occurred
occurred_at
DateTime!
Timestamp when the event occurred
account_id
String
Account ID that triggered the event
level
Int!
Event hierarchy level (0 for root events)
parent_id
String
Parent event ID for nested events
has_children
Boolean!
Whether this event has child events
primary_node
RelatedNode
Primary Infrahub node this event is associated with
Related Infrahub nodes for this event

Filtering Events

Use the params argument to filter subscribed events:

Branch Filter

subscription {
  query(
    name: "filtered-events"
    params: {
      branches: ["main", "develop"]
    }
  )
}

Custom Parameters

Different event types support different filter parameters. Check the event type documentation for available filters.

Best Practices

Set Appropriate Intervals

Balance real-time needs with server load:
# High frequency for critical updates
subscription {
  query(name: "critical", interval: 1000)
}

# Lower frequency for monitoring
subscription {
  query(name: "monitoring", interval: 10000)
}

Handle Reconnections

Always implement reconnection logic in your client:
const wsLink = new WebSocketLink({
  uri: 'wss://your-infrahub-instance/graphql',
  options: {
    reconnect: true,
    reconnectionAttempts: 5,
    connectionParams: async () => ({
      authToken: await getAuthToken(),
    }),
  },
});

Clean Up Subscriptions

Unsubscribe when no longer needed:
const subscription = client.subscribe({ query }).subscribe({
  next: handleEvent,
});

// Later...
subscription.unsubscribe();

Limitations

  • Subscriptions require WebSocket support
  • Authentication tokens must be valid for the entire subscription duration
  • Maximum concurrent subscriptions per client may be limited by server configuration
  • Events are delivered at the specified interval, not immediately

Example: Full Subscription Handler

import { ApolloClient, InMemoryCache, gql } from '@apollo/client';
import { WebSocketLink } from '@apollo/client/link/ws';

const wsLink = new WebSocketLink({
  uri: 'wss://infrahub.example.com/graphql',
  options: {
    reconnect: true,
    connectionParams: {
      authToken: 'your-jwt-token',
    },
  },
});

const client = new ApolloClient({
  link: wsLink,
  cache: new InMemoryCache(),
});

const BRANCH_EVENTS = gql`
  subscription BranchEvents {
    query(
      name: "branch-monitoring"
      interval: 3000
      params: { branches: ["main"] }
    )
  }
`;

const subscription = client.subscribe({
  query: BRANCH_EVENTS,
}).subscribe({
  next: ({ data }) => {
    console.log('Branch event received:', data);
    // Handle the event
  },
  error: (error) => {
    console.error('Subscription error:', error);
    // Handle error
  },
  complete: () => {
    console.log('Subscription completed');
  },
});

// Clean up on application shutdown
process.on('SIGTERM', () => {
  subscription.unsubscribe();
  client.stop();
});

See Also

Build docs developers (and LLMs) love