Overview
GraphQL subscriptions provide real-time updates when data changes on the server. 5Stack uses WebSocket connections to deliver live updates for matches, tournaments, chat messages, and player statistics.
Subscription Setup
Subscriptions require a WebSocket connection to the GraphQL endpoint:
import { createClient } from 'graphql-ws' ;
import { GraphQLWsLink } from '@apollo/client/link/subscriptions' ;
const wsClient = createClient ({
url: 'wss://{API_DOMAIN}/v1/graphql' ,
connectionParams: {
credentials: 'include' ,
},
});
const wsLink = new GraphQLWsLink ( wsClient );
Subscription Structure
Subscriptions are generated using the generateSubscription helper:
import { generateSubscription } from '@/graphql/graphqlGen' ;
import { $ } from '@/generated/zeus' ;
const subscription = generateSubscription ({
// Your subscription fields here
});
Match Subscriptions
Subscribe to Match Updates
Get real-time updates when a match changes:
import { generateSubscription } from '@/graphql/graphqlGen' ;
import { simpleMatchFields } from '@/graphql/simpleMatchFields' ;
import { $ } from '@/generated/zeus' ;
const subscription = generateSubscription ({
matches_by_pk: [
{ id: $ ( 'match_id' , 'uuid!' ) },
simpleMatchFields
]
});
Usage in Vue components:
< script >
import { generateSubscription } from '@/graphql/graphqlGen' ;
import { simpleMatchFields } from '@/graphql/simpleMatchFields' ;
import { $ } from '@/generated/zeus' ;
export default {
apollo: {
$subscribe: {
match: {
query: generateSubscription ({
matches_by_pk: [
{ id: $ ( 'match_id' , 'uuid!' ) },
simpleMatchFields
]
}),
variables () {
return {
match_id: this . matchId
};
},
result ({ data }) {
this . match = data . matches_by_pk ;
}
}
}
} ,
data () {
return {
matchId: 'your-match-uuid' ,
match: null
};
}
}
</ script >
This subscription will fire whenever the match status changes, lineups update, maps are vetoed, or scores change.
Subscribe to Match Lineup Stats
Get real-time player statistics during a live match:
import { generateSubscription } from '@/graphql/graphqlGen' ;
import { matchLineups } from '@/graphql/matchLineupsGraphql' ;
import { $ } from '@/generated/zeus' ;
const subscription = generateSubscription ({
match_lineups: [
{
where: {
match_id: { _eq: $ ( 'matchId' , 'uuid!' ) }
}
},
matchLineups
]
});
This subscription includes live updates for:
Player kills, deaths, and assists (KDA)
Headshot percentage
Damage dealt
Flash assists
Multi-kills (2K, 3K, 4K, 5K)
Utility usage statistics
Subscribe to Live Matches
Watch all currently active matches:
import { generateSubscription } from '@/graphql/graphqlGen' ;
import { simpleMatchFields } from '@/graphql/simpleMatchFields' ;
const subscription = generateSubscription ({
matches: [
{
where: {
status: { _in: [ 'Live' , 'Veto' ] }
},
order_by: [{ started_at: 'desc' }]
},
simpleMatchFields
]
});
Tournament Subscriptions
Subscribe to Tournament Updates
Get real-time updates for tournament status and bracket changes:
import { generateSubscription } from '@/graphql/graphqlGen' ;
import { simpleTournamentFields } from '@/graphql/simpleTournamentFields' ;
import { $ } from '@/generated/zeus' ;
const subscription = generateSubscription ({
tournaments_by_pk: [
{ id: $ ( 'tournament_id' , 'uuid!' ) },
simpleTournamentFields
]
});
Subscribe to Tournament Matches
Watch all matches in a tournament:
import { generateSubscription } from '@/graphql/graphqlGen' ;
import { simpleMatchFields } from '@/graphql/simpleMatchFields' ;
import { $ } from '@/generated/zeus' ;
const subscription = generateSubscription ({
matches: [
{
where: {
tournament_id: { _eq: $ ( 'tournament_id' , 'uuid!' ) }
},
order_by: [{ scheduled_at: 'asc' }]
},
simpleMatchFields
]
});
Server Subscriptions
Subscribe to Dedicated Server Status
Monitor a game server’s status:
import { generateSubscription } from '@/graphql/graphqlGen' ;
import { $ } from '@/generated/zeus' ;
const subscription = generateSubscription ({
servers_by_pk: [
{ id: $ ( 'serverId' , 'uuid!' ) },
{
id: true ,
name: true ,
status: true ,
current_map: true ,
current_players: true ,
max_players: true ,
ip: true ,
port: true
}
]
});
Subscribe to Available Servers
import { generateSubscription } from '@/graphql/graphqlGen' ;
const subscription = generateSubscription ({
servers: [
{
where: {
status: { _eq: 'Available' },
enabled: { _eq: true }
}
},
{
id: true ,
name: true ,
region: true ,
max_players: true
}
]
});
Database Subscriptions
Subscribe to Database Backups
Monitor database backup operations:
import { generateSubscription } from '@/graphql/graphqlGen' ;
const subscription = generateSubscription ({
db_backups: [
{},
{
id: true ,
name: true ,
size: true ,
status: true ,
created_at: true ,
completed_at: true ,
error_message: true
}
]
});
Usage example:
< script >
export default {
apollo: {
$subscribe: {
backups: {
query: generateSubscription ({
db_backups: [
{},
{
id: true ,
name: true ,
size: true ,
status: true ,
created_at: true
}
]
}),
result ({ data }) {
this . backups = data . db_backups ;
}
}
}
}
}
</ script >
Player Subscriptions
Subscribe to Player Updates
Watch changes to a player’s profile:
import { generateSubscription } from '@/graphql/graphqlGen' ;
import { playerFields } from '@/graphql/playerFields' ;
import { $ } from '@/generated/zeus' ;
const subscription = generateSubscription ({
players_by_pk: [
{ steam_id: $ ( 'steam_id' , 'String!' ) },
playerFields
]
});
Subscribe to Player ELO Changes
import { generateSubscription } from '@/graphql/graphqlGen' ;
import { $ } from '@/generated/zeus' ;
const subscription = generateSubscription ({
players_by_pk: [
{ steam_id: $ ( 'steam_id' , 'String!' ) },
{
steam_id: true ,
name: true ,
elo: true ,
elo_history: [
{
order_by: [{ created_at: 'desc' }],
limit: 10
},
{
elo: true ,
created_at: true ,
match_id: true
}
]
}
]
});
Chat Subscriptions
Subscribe to Chat Messages
Receive real-time chat messages for a lobby:
import { generateSubscription } from '@/graphql/graphqlGen' ;
import { $ } from '@/generated/zeus' ;
const subscription = generateSubscription ({
chat_messages: [
{
where: {
lobby_id: { _eq: $ ( 'lobby_id' , 'uuid!' ) }
},
order_by: [{ created_at: 'asc' }],
limit: 100
},
{
id: true ,
message: true ,
created_at: true ,
player: {
steam_id: true ,
name: true ,
avatar_url: true ,
role: true
}
}
]
});
Subscription Patterns
Unsubscribing
Always clean up subscriptions when components unmount:
export default {
beforeUnmount () {
// Apollo automatically unsubscribes when component unmounts
// Manual cleanup for custom subscriptions:
if ( this . $apollo ?. subscriptions ) {
Object . keys ( this . $apollo . subscriptions ). forEach ( key => {
this . $apollo . subscriptions [ key ]. unsubscribe ();
});
}
}
}
Conditional Subscriptions
Start subscriptions conditionally:
export default {
apollo: {
$subscribe: {
match: {
query: generateSubscription ({ /* ... */ }),
skip () {
// Skip subscription if no match ID
return ! this . matchId ;
},
variables () {
return { match_id: this . matchId };
}
}
}
}
}
Handling Errors
export default {
apollo: {
$subscribe: {
match: {
query: generateSubscription ({ /* ... */ }),
variables () {
return { match_id: this . matchId };
},
result ({ data }) {
this . match = data . matches_by_pk ;
},
error ( error ) {
console . error ( 'Subscription error:' , error );
this . $toast ({
variant: 'destructive' ,
title: 'Connection Error' ,
description: 'Failed to receive live updates'
});
}
}
}
}
}
Only subscribe to the specific fields you need. Avoid subscribing to large datasets or deeply nested relationships unless necessary.
Filter subscriptions at the database level using where clauses instead of filtering in the client.
Use limit clauses to restrict the number of records returned, especially for lists.
For rapidly changing data, consider debouncing updates in your UI to reduce re-renders.
WebSocket Connection Management
Connection States
Monitor WebSocket connection state:
const wsClient = createClient ({
url: 'wss://{API_DOMAIN}/v1/graphql' ,
connectionParams: {
credentials: 'include' ,
},
on: {
connected : () => console . log ( 'WebSocket connected' ),
closed : () => console . log ( 'WebSocket closed' ),
error : ( error ) => console . error ( 'WebSocket error:' , error )
}
});
Reconnection
The GraphQL WebSocket client automatically handles reconnection with exponential backoff. You can customize this behavior:
const wsClient = createClient ({
url: 'wss://{API_DOMAIN}/v1/graphql' ,
retryAttempts: 5 ,
retryWait : ( retries ) => {
// Exponential backoff: 1s, 2s, 4s, 8s, 16s
return new Promise ( resolve =>
setTimeout ( resolve , Math . min ( 1000 * Math . pow ( 2 , retries ), 30000 ))
);
}
});
Next Steps
Queries Learn about querying initial data
Mutations Trigger subscriptions with mutations