Django Channels
Strawberry provides an integration with django-channels to enable subscriptions and WebSocket support with Django.
Overview
Django doesn’t support WebSockets out of the box. Django Channels extends Django to handle WebSockets and other asynchronous protocols. Strawberry’s Channels integration allows you to:
- Use GraphQL subscriptions
- Handle GraphQL over WebSocket connections
- Mix regular Django HTTP requests with GraphQL
Installation
Install the required packages:
pip install channels daphne For production deployments, you may also need a channel layer backend:
pip install channels-redis # For Redis-backed channel layers Configuration
1. Update INSTALLED_APPS
Add daphne and channels to your INSTALLED_APPS in settings.py :
INSTALLED_APPS = [ 'daphne', # Must be before staticfiles for runserver override 'django.contrib.staticfiles', # ... other apps 'channels', 'strawberry_django',] 2. Configure ASGI Application
Set the ASGI application path:
ASGI_APPLICATION = 'myproject.asgi.application' 3. Set Up ASGI Routing
Create or update your asgi.py file:
import os
from django.core.asgi import get_asgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
# Initialize Django ASGI application early to ensure AppRegistry is populated# before importing any modelsdjango_asgi_app = get_asgi_application()
# Import schema AFTER django setupfrom myproject.schema import schemafrom strawberry_django.routers import AuthGraphQLProtocolTypeRouter
application = AuthGraphQLProtocolTypeRouter( schema, django_application=django_asgi_app,) AuthGraphQLProtocolTypeRouter
strawberry_django provides AuthGraphQLProtocolTypeRouter , a convenience class that sets up GraphQL on both HTTP and WebSocket with authentication support.
from strawberry_django.routers import AuthGraphQLProtocolTypeRouter
application = AuthGraphQLProtocolTypeRouter( schema, # Your Strawberry schema django_application=django_asgi, # Optional: Django ASGI app for non-GraphQL routes url_pattern="^graphql", # Optional: URL pattern (default: "^graphql")) What it provides
- AuthMiddlewareStack: Automatically populates
request.userfor authenticated sessions - AllowedHostsOriginValidator: WebSocket security based on
ALLOWED_HOSTS - Dual protocol routing: Routes both HTTP and WebSocket to GraphQL
Custom URL Pattern
# Route GraphQL to /api/graphql instead of /graphqlapplication = AuthGraphQLProtocolTypeRouter( schema, django_application=django_asgi_app, url_pattern="^api/graphql",) Difference from Strawberry’s GraphQLProtocolTypeRouter
Strawberry core provides GraphQLProtocolTypeRouter , but strawberry_django provides AuthGraphQLProtocolTypeRouter with these enhancements:
| Feature | GraphQLProtocolTypeRouter | AuthGraphQLProtocolTypeRouter |
|---|---|---|
| Auth middleware | No | Yes (AuthMiddlewareStack) |
| Host validation | No | Yes (AllowedHostsOriginValidator) |
request.user available | No | Yes |
Use AuthGraphQLProtocolTypeRouter when you need:
- User authentication in resolvers
- Permission checks
- Session-based authentication
Channel Layers
For subscriptions that need to broadcast to multiple clients (e.g., chat applications), configure a channel layer:
# Development (in-memory, single-process only)CHANNEL_LAYERS = { "default": { "BACKEND": "channels.layers.InMemoryChannelLayer" }}
# Production (Redis)CHANNEL_LAYERS = { "default": { "BACKEND": "channels_redis.core.RedisChannelLayer", "CONFIG": { "hosts": [("127.0.0.1", 6379)], }, },} Accessing User in Resolvers
With AuthGraphQLProtocolTypeRouter , you can access the authenticated user:
import strawberryfrom strawberry.types import Info
@strawberry.typeclass Query: @strawberry.field def me(self, info: Info) -> str: user = info.context.request.user if user.is_authenticated: return f"Hello, {user.username}!" return "Hello, anonymous!" Running the Server
Development
With Daphne installed and configured, runserver automatically uses ASGI:
python manage.py runserver Production
Use an ASGI server like Daphne, Uvicorn, or Hypercorn:
# Daphnedaphne myproject.asgi:application
# Uvicornuvicorn myproject.asgi:application --host 0.0.0.0 --port 8000
# Hypercornhypercorn myproject.asgi:application --bind 0.0.0.0:8000 Advanced: Custom Routing
For more complex setups, you can create custom routing:
import os
from channels.auth import AuthMiddlewareStackfrom channels.routing import ProtocolTypeRouter, URLRouterfrom channels.security.websocket import AllowedHostsOriginValidatorfrom django.core.asgi import get_asgi_applicationfrom django.urls import re_pathfrom strawberry.channels.handlers.http_handler import GraphQLHTTPConsumerfrom strawberry.channels.handlers.ws_handler import GraphQLWSConsumer
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")django_asgi_app = get_asgi_application()
from myproject.schema import schema
application = ProtocolTypeRouter({ "http": AuthMiddlewareStack( URLRouter([ re_path(r"^graphql$", GraphQLHTTPConsumer.as_asgi(schema=schema)), re_path(r"^", django_asgi_app), ]) ), "websocket": AllowedHostsOriginValidator( AuthMiddlewareStack( URLRouter([ re_path(r"^graphql$", GraphQLWSConsumer.as_asgi(schema=schema)), ]) ) ),}) Troubleshooting
Subscriptions not working
- Check ASGI_APPLICATION is correctly set in settings
- Ensure schema is imported after
get_asgi_application()to avoid AppRegistryNotReady errors - Use an ASGI server - standard
runserverwithout Daphne uses WSGI
User is AnonymousUser
- Ensure you’re using
AuthGraphQLProtocolTypeRouter(notGraphQLProtocolTypeRouter) - Check that
AuthMiddlewareStackis in your routing - Verify session cookies are being sent with WebSocket requests
WebSocket connection refused
- Check
ALLOWED_HOSTSin settings includes your hostname - Ensure the URL pattern matches your client’s WebSocket URL
- Check browser console for CORS or security errors
See Also
- Subscriptions Guide - Creating subscriptions
- Strawberry Channels Docs - Core integration docs
- Django Channels Docs - Full Channels documentation