Message patterns

This page describes common messaging patterns used with Django-AWS-API-Gateway-WebSockets.

The package supports sending messages from Django to connected WebSocket clients through AWS API Gateway.

Common patterns include:

  • replying to the current connection;

  • sending to one stored session;

  • sending to all sessions for a user;

  • sending to all sessions in a channel;

  • broadcasting to all connected sessions;

  • sending toast notifications;

  • sending task progress updates;

  • sending lightweight invalidation messages;

  • handling stale connections.

Overview

AWS API Gateway owns the WebSocket connection.

Django sends messages back to clients using the API Gateway Management API.

The package provides two main ways to send messages:

WebSocketSession.send_message()

Send to one specific WebSocket connection.

WebSocketSession.objects.filter(...).send_message()

Send to all connected sessions in a queryset.

The queryset version sends to connected sessions in the queryset.

Message shape

Messages should be JSON-compatible dictionaries.

A useful convention is to include a type field.

Example:

{
    "type": "notification",
    "message": "You have a new notification.",
}

The frontend can then switch behaviour based on type.

Example browser handler:

socket.onmessage = function (event) {
    const data = JSON.parse(event.data);

    if (data.type === "notification") {
        showNotification(data.message);
        return;
    }

    if (data.type === "chat_message") {
        appendChatMessage(data.username, data.message);
        return;
    }

    console.log("Unhandled message:", data);
};

Reply to the current connection

Use this pattern when the server should respond only to the client that sent the message.

Example use cases:

  • acknowledgement;

  • validation error;

  • request result;

  • private notification;

  • task status for one user.

Example:

from django.http import JsonResponse

from django_aws_api_gateway_websockets.views import WebSocketView


class ExampleWebSocketView(WebSocketView):
    def default(self, request, *args, **kwargs):
        self.websocket_session.send_message(
            {
                "type": "reply",
                "message": "Django received your message.",
            }
        )

        return JsonResponse({"ok": True})

This sends a message only to the current WebSocket connection.

Send to one stored session

You can also send to a specific stored WebSocketSession.

Example:

from django_aws_api_gateway_websockets.models import WebSocketSession

session = WebSocketSession.objects.get(pk=1)

session.send_message(
    {
        "type": "notification",
        "message": "This message was sent to one connection.",
    }
)

This is useful when you have stored or looked up a specific session.

Send to a user’s active sessions

A user may have multiple active WebSocket sessions, such as multiple browser tabs or devices.

You can send a message to all active sessions for one user.

from django.contrib.auth import get_user_model

User = get_user_model()

user = User.objects.get(username="alice")

user.websocket_sessions.filter(
    connected=True,
).send_message(
    {
        "type": "notification",
        "message": "This message was sent to all of Alice's active sessions.",
    }
)

Send to a channel

Channels are used to group WebSocket sessions.

Example use cases:

  • chat rooms;

  • dashboards;

  • tenant updates;

  • project updates;

  • document collaboration;

  • notification streams.

Example:

from django_aws_api_gateway_websockets.models import WebSocketSession

WebSocketSession.objects.filter(
    channel_name="general",
).send_message(
    {
        "type": "chat_message",
        "channel": "general",
        "username": "alice",
        "message": "Hello general room.",
    }
)

This sends the message to active sessions in the general channel.

Broadcast to all connected sessions

Broadcasting sends a message to all active WebSocket sessions.

Example use cases:

  • maintenance warnings;

  • system-wide announcements;

  • incident notices;

  • global feature flags or reload notices.

Example:

from django_aws_api_gateway_websockets.models import WebSocketSession

WebSocketSession.objects.filter(
    connected=True,
).send_message(
    {
        "type": "system",
        "level": "warning",
        "message": "Maintenance will begin in 5 minutes.",
    }
)

Use broadcast carefully. Large or frequent broadcasts may increase AWS usage and application load.

Send a toast notification

Toast notifications are a common WebSocket pattern.

Server-side example:

self.websocket_session.send_message(
    {
        "type": "toast",
        "level": "success",
        "title": "Saved",
        "message": "Your changes have been saved.",
    }
)

Frontend example:

socket.onmessage = function (event) {
    const data = JSON.parse(event.data);

    if (data.type === "toast") {
        showToast(data.level, data.title, data.message);
        return;
    }
};

function showToast(level, title, message) {
    console.log(`[${level}] ${title}: ${message}`);
}

Toast payloads commonly include:

  • type;

  • level;

  • title;

  • message;

  • optional timeout;

  • optional action URL.

Send task progress

WebSockets are useful for showing progress from long-running work.

Example server-side message:

WebSocketSession.objects.filter(
    channel_name="task_123",
).send_message(
    {
        "type": "task_progress",
        "task_id": 123,
        "percent": 75,
        "message": "Processing records.",
    }
)

Frontend handler:

socket.onmessage = function (event) {
    const data = JSON.parse(event.data);

    if (data.type === "task_progress") {
        updateProgressBar(data.task_id, data.percent, data.message);
        return;
    }
};

For long-running background jobs, a common pattern is:

  1. create a channel for the task;

  2. connect the browser to that channel;

  3. send progress updates to the channel;

  4. send a completion message when finished.

Send lightweight invalidation messages

For larger data updates, avoid sending the full data over WebSocket.

Instead, send a small invalidation message and let the browser fetch the updated data over HTTPS.

Example:

WebSocketSession.objects.filter(
    channel_name="dashboard",
).send_message(
    {
        "type": "resource_updated",
        "resource": "order",
        "id": 123,
        "fetch_url": "/api/orders/123/",
    }
)

Frontend:

socket.onmessage = async function (event) {
    const data = JSON.parse(event.data);

    if (data.type === "resource_updated") {
        const response = await fetch(data.fetch_url);
        const resource = await response.json();
        updatePage(resource);
    }
};

This keeps WebSocket messages small and avoids duplicating normal HTTP API behaviour.

Chat room message

A typical chat message pattern is:

  1. browser sends a message to Django;

  2. Django validates and stores the message;

  3. Django sends the message to all sessions in the same channel.

Example:

from django.http import JsonResponse

from django_aws_api_gateway_websockets.models import WebSocketSession
from django_aws_api_gateway_websockets.views import WebSocketView


class ChatWebSocketView(WebSocketView):
    def chat_message(self, request, *args, **kwargs):
        room = self.websocket_session.channel_name
        text = self.body.get("message", "").strip()

        if not text:
            return JsonResponse(
                {
                    "ok": False,
                    "error": "Message cannot be empty.",
                },
                status=400,
            )

        WebSocketSession.objects.filter(
            channel_name=room,
        ).send_message(
            {
                "type": "chat_message",
                "room": room,
                "username": request.user.get_username(),
                "message": text,
            }
        )

        return JsonResponse({"ok": True})

See Full chat room example for a fuller chat room example.

Admin broadcast

A systems administrator can broadcast from the Django shell.

python manage.py shell

Then:

from django_aws_api_gateway_websockets.models import WebSocketSession

WebSocketSession.objects.filter(
    connected=True,
).send_message(
    {
        "type": "system",
        "level": "warning",
        "message": "Maintenance will begin in 5 minutes.",
    }
)

Message size limits

AWS API Gateway WebSocket messages have size limits.

Keep messages compact.

Recommended patterns:

  • send IDs instead of full objects;

  • send URLs for the browser to fetch larger data;

  • avoid sending large lists;

  • avoid sending binary data directly;

  • compress or paginate data through normal HTTP APIs if needed.

Good WebSocket message:

{
  "type": "report_ready",
  "report_id": 123,
  "fetch_url": "/reports/123/"
}

Poor WebSocket message:

{
  "type": "report_ready",
  "rows": [
    "thousands of rows of data"
  ]
}

Handling stale connections

Clients may disconnect unexpectedly.

When sending a message, AWS may report that a connection is gone.

This can happen when:

  • a browser tab closes;

  • a laptop sleeps;

  • a mobile network changes;

  • API Gateway times out the connection;

  • a stale session remains in the database.

Treat stale connections as normal operational behaviour.

Schedule cleanup:

python manage.py clearWebSocketSessions

See Clean-up.

Security considerations

Validate incoming messages

Do not trust client payloads.

Validate:

  • required fields;

  • string lengths;

  • object IDs;

  • user permissions;

  • channel access;

  • message type;

  • allowed actions or handlers.

Do not trust channel names

A client can request a channel name.

Always check whether the user is allowed to use that channel.

Avoid sensitive data in messages

Only send data the connected user is allowed to see.

If broadcasting or multicasting, confirm that every recipient should receive the message.

Use permissions

Use Django permissions and object-level checks where needed.

See Permissions.

Testing message patterns

When testing message patterns:

  • mock AWS API Gateway Management API calls;

  • test unicast sends;

  • test channel sends;

  • test broadcasts;

  • test permission failures;

  • test stale connection handling;

  • test message size behaviour;

  • test frontend handling of each type.

See Testing.