Skip to main content
WebSockets Tutorial
CHAPTER 13 Beginner

Working with JSON Data in WebSockets

Updated: May 14, 2026
20 min read

# CHAPTER 13

Working with JSON Data in WebSockets

1. Introduction

When working with HTTP REST APIs, the concept of "endpoints" (/users, /posts, /comments) naturally separates your logic. WebSockets, however, have only one endpoint—the open connection. Whether a user is sending a chat message, updating their profile picture, or joining a room, all data flows through the exact same pipe. How do we organize this? In this chapter, we will learn how to use structured JSON payloads to route messages effectively.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Explain why WebSockets require an internal routing mechanism.
  • Design standardized JSON payload structures.
  • Implement a switch/case router on the client and server.
  • Safely serialize and deserialize JSON data.

3. Beginner-Friendly Explanation

Imagine a massive postal sorting facility. In HTTP, there are separate doors for different types of mail: Door 1 for Letters, Door 2 for Packages. In WebSockets, there is only one giant door. Everything gets dumped onto a single conveyor belt. To make sense of it all, every single item must have a clear label taped to it saying exactly what it is. In code, this label is a JSON object with a property like type: "chatmessage" or event: "userjoined".

4. Real-World Examples

  • Multiplayer Game: The client might receive 100 messages a second. Some messages update player positions ({"event": "move"}), others update the game clock ({"event": "tick"}). The client uses the event type to decide which JavaScript function should process the data.

5. Designing the Payload Structure

A professional WebSocket application standardizes a specific JSON structure and never deviates from it. A common pattern includes two main keys: type (the action) and payload (the data).

6. JSON Structure Examples

Every message sent by the Client to the Server should look like this:
json
1234567
{
  "type": "send_message",
  "payload": {
    "room_id": 10,
    "text": "Hello everyone!"
  }
}

Every message sent by the Server to the Client should look like this:

json
12345678
{
  "type": "new_message",
  "payload": {
    "user": "Alice",
    "text": "Hello everyone!",
    "timestamp": "10:04 AM"
  }
}

7. Client-Side Routing Example

When the client receives a message, it parses the JSON and routes it to the appropriate function.
javascript
1234567891011121314151617181920212223242526
socket.onmessage = function(event) {
    try {
        const data = JSON.parse(event.data);
        
        // The Router
        switch(data.type) {
            case 'new_message':
                displayChat(data.payload);
                break;
            case 'user_joined':
                showNotification(data.payload.username + " joined.");
                break;
            case 'error':
                alert("Error: " + data.payload.message);
                break;
            default:
                console.warn("Unknown message type:", data.type);
        }
    } catch (e) {
        console.error("Received non-JSON data:", event.data);
    }
};

function displayChat(payload) {
    console.log(`[${payload.timestamp}] ${payload.user}: ${payload.text}`);
}

8. Server-Side Routing Concept

The backend (e.g., PHP) uses the exact same pattern to process incoming messages.
php
123456789101112
<?php
// Conceptual PHP Router
$data = json_decode($incomingMsg, true);

switch($data[&#039;type']) {
    case &#039;join_room':
        $roomManager->addUserToRoom($conn, $data[&#039;payload']['room_id']);
        break;
    case &#039;send_message':
        $roomManager->broadcast($data[&#039;payload']);
        break;
}

9. Handling Errors via JSON

Because the native WebSocket onerror event doesn't provide detail, the server should send business-logic errors as JSON messages before dropping the connection.
json
1234567
{
  "type": "error",
  "payload": {
    "code": 403,
    "message": "You do not have permission to join this room."
  }
}

10. Best Practices

  • Always use try...catch: Malformed JSON will cause JSON.parse() to throw a fatal error, which will crash your entire JavaScript execution and freeze the UI. Always wrap parsing in a try/catch block.
  • Keep Payloads Flat: Avoid infinitely deeply nested JSON objects. Flat, simple structures are faster to parse and easier to debug.

11. Common Mistakes

  • Sending raw strings mixed with JSON: If you decide to use JSON, use it for *everything*. Do not send socket.send("Ping") one minute and socket.send(JSON.stringify({...})) the next. It makes the parser logic messy. Send {"type": "ping"} instead.

12. Mini Exercises

  1. 1. Look at the JSON structure in Section 6.
  1. 2. Write a JSON object that represents a user clicking a "Like" button on a specific photo. What is the type? What is in the payload?
*(Answer: type: "likephoto", payload: { photoid: 42, user_id: 7 })*

13. Coding Challenges

Challenge 1: Write a JavaScript helper function called sendSocketEvent(type, payload) that automatically takes a type string and a payload object, wraps them together, JSON.stringifys them, and sends them via the WebSocket.

14. MCQs with Answers

Question 1

Why is a switch/case or router necessary in WebSocket onmessage handlers?

Question 2

What will happen if event.data contains "Hello World" and you run JSON.parse(event.data)?

15. Interview Questions

  • Q: Contrast routing in a traditional REST API versus routing over a WebSocket connection.
  • Q: Explain why a standard envelope structure (e.g., type and payload) is a best practice for real-time messaging.

16. FAQs

Q: Can I send XML instead of JSON? A: You can send any text format you want over WebSockets (XML, CSV, plain text). However, JSON is universally the standard because it maps natively to JavaScript objects and is highly efficient.

17. Summary

In Chapter 13, we learned how to bring order to the chaos of a single, continuous stream of data. By establishing a strict JSON envelope containing a type and a payload, we can build powerful routing logic on both the client and the server, allowing a single connection to handle dozens of different features simultaneously.

18. Next Chapter Recommendation

With our routing system in place, we can start building features beyond simple chat. Proceed to Chapter 14: Real-Time Notifications System to learn how to push alerts and badges to users instantly.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·