Routing
Chanx provides Django-style routing utilities specifically designed for WebSocket applications. These functions work similarly to Django's URL routing but are optimized for Channels and ASGI applications.
Key Components
Chanx's routing system includes:
Django-like URL pattern matching with
path()andre_path()Modular routing with
include()Type-safe URL converters
Consistent naming conventions for better organization
Separation between HTTP routing (
django.urls) and WebSocket routing (chanx.routing)
Routing Organization
For optimal organization, structure your routing like this:
Create a
routing.pyfile in each app with WebSocket consumersName the main URLRouter variable
router(similar to Django'surlpatterns)Create a project-level
routing.pythat includes app-specific routersUse
chanx.routingfor WebSocket routes anddjango.urlsfor HTTP routes
App-Level Routing
# chat/routing.py
from channels.routing import URLRouter
from chanx.routing import path, re_path
from chat.consumers import ChatConsumer, ChatDetailConsumer
# Important: Name this variable 'router' for string-based includes
router = URLRouter([
path('room/<str:room_id>/', ChatConsumer.as_asgi()),
re_path(r'(?P<pk>\d+)/', ChatDetailConsumer.as_asgi()),
])
Project-Level Routing
# myproject/routing.py
from channels.routing import URLRouter
from chanx.routing import path, include
# Main router for the project
router = URLRouter([
# String-based include (requires router variable in chat/routing.py)
path('chat/', include('chat.routing')),
path('notifications/', include('notifications.routing')),
path('assistants/', include('assistants.routing')),
])
ASGI Configuration
# myproject/asgi.py
import os
from django.core.asgi import get_asgi_application
from channels.routing import ProtocolTypeRouter
from channels.security.websocket import OriginValidator
from channels.sessions import CookieMiddleware
from django.conf import settings
from chanx.routing import include
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myproject.settings')
django_asgi_app = get_asgi_application()
application = ProtocolTypeRouter({
"http": django_asgi_app,
"websocket": OriginValidator(
CookieMiddleware(include("myproject.routing")),
settings.CORS_ALLOWED_ORIGINS + settings.CSRF_TRUSTED_ORIGINS,
),
})
URL Patterns
Chanx provides path() and re_path() functions that work exactly like Django's URL functions but are specifically designed for WebSocket routing:
from chanx.routing import path, re_path
# Path with converter
path('users/<int:user_id>/', UserConsumer.as_asgi())
# Regular expression pattern
re_path(r'^rooms/(?P<room_id>\w+)/$', RoomConsumer.as_asgi())
Note: Use chanx.routing for WebSocket endpoints and django.urls for HTTP endpoints to maintain clear separation between routing concerns.
URL Path Converters
Chanx supports the same path converters as Django:
str: Matches any non-empty string without a slashint: Matches zero or any positive integerslug: Matches ASCII letters, numbers, hyphens, or underscoresuuid: Matches a formatted UUIDpath: Matches any non-empty string, including slashes
path('rooms/<str:room_name>/', RoomConsumer.as_asgi())
path('users/<int:user_id>/', UserConsumer.as_asgi())
path('profiles/<slug:username>/', ProfileConsumer.as_asgi())
path('files/<path:file_path>/', FileConsumer.as_asgi())
path('sessions/<uuid:session_id>/', SessionConsumer.as_asgi())
Modular Routing with include()
The include() function lets you organize routing in a modular way:
from chanx.routing import include
# Include by string reference (uses 'router' variable in the module)
path('chat/', include('chat.routing'))
# Include a router instance directly
path('api/', include(api_router))
Accessing URL Parameters
In your consumer, access URL parameters through the scope:
async def build_groups(self):
# Get URL parameters
room_id = self.scope["url_route"]["kwargs"].get("room_id")
return [f"room_{room_id}"]
Using with Object-Level Permissions
URL parameters are automatically used for object lookup when using querysets:
class RoomConsumer(AsyncJsonWebsocketConsumer[Room]):
queryset = Room.objects.all()
permission_classes = [IsRoomMember]
async def build_groups(self):
# self.obj is automatically loaded from URL parameter 'pk' or 'id'
return [f"room_{self.obj.pk}"]
Best Practices
Consistent naming: Use
routing.pyand name the variablerouterModular organization: Group related endpoints in app-specific routing files
Descriptive paths: Use descriptive URL patterns that reflect resource hierarchy
Prefer path() over re_path(): Use path converters when possible for readability
Type safety: Use proper type hints in URL parameters
Separation of concerns: Use
chanx.routingfor WebSocket routes anddjango.urlsfor HTTP routes
Next Steps
Consumers - Learn about WebSocket consumers
Authentication - Understand authentication with WebSockets