WebSocket realtime
15. WebSocket Real-time Updates
Connection
The backend provides WebSocket support for real-time updates. Connect to:
ws://localhost:3000/wsFor production with HTTPS:
wss://your-domain.com/wsAuthentication
WebSocket connections are authenticated using session cookies:
- First, login via the REST API to establish a session
- The WebSocket connection will automatically use the session cookie
- Unauthenticated connections will be rejected
Connection Lifecycle
- Connect: Open WebSocket connection to
/ws - Authentication: Server verifies session cookie
- Confirmation: Server sends
{"type": "connected", "message": "...", "userId": ...} - Subscribe: Send subscribe messages for specific events
- Receive Updates: Server broadcasts real-time events
- Disconnect: Close connection or server closes on authentication failure
Message Format
Client to Server
Subscribe to events:
{
"type": "subscribe",
"channel": "order_changes"
}Unsubscribe from events:
{
"type": "unsubscribe",
"channel": "order_changes"
}Ping (keepalive):
{
"type": "ping"
}Server to Client
Connection confirmation:
{
"type": "connected",
"message": "WebSocket connection established",
"userId": 1
}Real-time event:
{
"event": "order:created",
"data": {
"id": 123,
"order_number": "ORD-1234567890",
"status": "pending",
"payment_status": "pending",
"total": 99.99,
"customer_id": 45,
"currency": "USD"
},
"timestamp": "2026-01-25T10:30:00.000Z"
}Error:
{
"type": "error",
"message": "Error description"
}Pong (response to ping):
{
"type": "pong"
}Available Events
Order Events
order:created- New order createdorder:updated- Order status or details updatedorder:deleted- Order deleted
Event Payload:
{
"event": "order:updated",
"data": {
"id": 123,
"order_number": "ORD-1234567890",
"status": "processing",
"payment_status": "paid",
"total": 99.99,
"customer_id": 45,
"currency": "USD",
"changed_fields": {
"status": "processing",
"payment_status": "paid"
}
},
"timestamp": "2026-01-25T10:30:00.000Z"
}Product Events
product:created- New product createdproduct:updated- Product details updatedproduct:deleted- Product deleted
Event Payload:
{
"event": "product:updated",
"data": {
"id": 456,
"name": "Product Name",
"sku": "SKU-123",
"status": "published",
"price": 29.99,
"stock": 100,
"changed_fields": {
"price": 29.99,
"stock": 100
}
},
"timestamp": "2026-01-25T10:30:00.000Z"
}Customer Events
customer:created- New customer registeredcustomer:updated- Customer details updatedcustomer:deleted- Customer deleted
Event Payload:
{
"event": "customer:updated",
"data": {
"id": 789,
"email": "customer@example.com",
"first_name": "John",
"last_name": "Doe",
"changed_fields": {
"email": "customer@example.com"
}
},
"timestamp": "2026-01-25T10:30:00.000Z"
}Shipment Events
shipment:created- New shipment createdshipment:updated- Shipment status or tracking updatedshipment:deleted- Shipment deleted
Event Payload:
{
"event": "shipment:updated",
"data": {
"id": 101,
"order_id": 123,
"tracking_number": "TRACK123456",
"status": "shipped",
"carrier": "UPS",
"changed_fields": {
"status": "shipped",
"tracking_number": "TRACK123456"
}
},
"timestamp": "2026-01-25T10:30:00.000Z"
}Transaction Events
transaction:created- New transaction createdtransaction:updated- Transaction status updatedtransaction:deleted- Transaction deleted
Event Payload:
{
"event": "transaction:created",
"data": {
"id": 202,
"order_id": 123,
"type": "payment",
"status": "completed",
"amount": 99.99,
"gateway": "stripe"
},
"timestamp": "2026-01-25T10:30:00.000Z"
}Error Handling
- Connection Errors: WebSocket will attempt to reconnect automatically
- Authentication Errors: Connection is closed with code 1008
- Invalid Messages: Server responds with error message
- Rate Limiting: Excessive connections may be rate-limited
Best Practices
- Reconnection: Implement exponential backoff for reconnections
- Heartbeat: Send ping messages periodically to keep connection alive
- Error Handling: Handle connection errors gracefully
- Subscription Management: Subscribe only to events you need
- Message Validation: Validate all incoming messages before processing
Example Client Implementation
const ws = new WebSocket('ws://localhost:3000/ws');
ws.onopen = () => {
console.log('Connected');
// Subscribe to order events
ws.send(JSON.stringify({ type: 'subscribe', channel: 'order_changes' }));
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.event && message.data) {
// Handle real-time event
console.log('Event:', message.event, message.data);
// Update UI or invalidate queries
if (message.event === 'order:created') {
// Refresh orders list
invalidateQueries(['orders']);
}
}
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('Disconnected, attempting to reconnect...');
// Implement reconnection logic
};