Group Configuration
Groups organize your Django REST Framework API into logical sections for different features, teams, or microservices. Django-CFG’s API client generator creates separate clients for each group.
Understanding Groups
A group is a collection of Django apps that share:
- Related functionality
- Common domain logic
- Target audience or purpose
- Similar access patterns
Each group gets:
- Separate OpenAPI schema - Independent API documentation
- Generated TypeScript client - Type-safe frontend client
- Generated Python client - Async backend client
- Generated Go client - Type-safe Go HTTP client
- Generated Swift client - Native iOS/macOS client (optional)
- Generated Proto files - gRPC service definitions
- API documentation - Swagger UI and Redoc
Configuration
Basic Group
Configure groups in your Django-CFG configuration:
# api/config.py
from django_cfg import DjangoConfig, OpenAPIConfig, OpenAPIGroupConfig
class CryptoConfig(DjangoConfig):
openapi: OpenAPIConfig = OpenAPIConfig(
enabled=True,
groups=[
OpenAPIGroupConfig(
name="core",
apps=["users", "accounts", "api_keys"],
title="Core API",
description="User management and API keys",
),
],
)Multiple Groups
Organize large APIs into logical groups:
openapi: OpenAPIConfig = OpenAPIConfig(
enabled=True,
generate_package_files=True,
generate_zod_schemas=True,
generate_fetchers=True,
generate_swr_hooks=True,
output_dir="openapi",
groups=[
# Core functionality
OpenAPIGroupConfig(
name="core",
apps=["users", "accounts", "api_keys", "webhooks"],
title="Core API",
description="User management, API keys, and webhooks",
),
# Trading
OpenAPIGroupConfig(
name="trading",
apps=["wallets", "orders", "transactions", "positions"],
title="Trading API",
description="Crypto wallets and trading operations",
),
# Market data
OpenAPIGroupConfig(
name="market",
apps=["prices", "charts", "orderbooks", "tickers"],
title="Market API",
description="Real-time market data and price feeds",
),
# Portfolio and analytics
OpenAPIGroupConfig(
name="portfolio",
apps=["holdings", "pnl", "reports", "alerts"],
title="Portfolio API",
description="Portfolio tracking and analytics",
),
],
)OpenAPIGroupConfig Parameters
| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
name | str | - | Yes | Unique group identifier. Lowercase, no spaces. Used in URLs (/schema/{name}/) and file paths (openapi/{name}/) |
apps | List[str] | - | Yes | Django app labels to include. Supports wildcards (e.g., "django_cfg.*") |
title | str | - | Yes | Human-readable title. Shown in Swagger UI and Redoc |
description | str | "" | No | Detailed explanation of group purpose |
version | str | "v1" | No | API version (semantic versioning recommended) |
auth_required | bool | False | No | Whether authentication is required for this group |
Examples:
# Minimal
OpenAPIGroupConfig(name="core", apps=["users", "accounts"], title="Core API")
# Full
OpenAPIGroupConfig(
name="trading",
apps=["wallets", "orders", "transactions"],
title="Trading API",
description="Crypto wallets and trading operations",
version="v2",
auth_required=True,
)Generated Structure
Output Directory
Each group generates its own directory structure:
openapi/
├── schemas/ # OpenAPI schemas
│ ├── core.yaml
│ ├── shop.yaml
│ └── content.yaml
│
├── clients/
│ ├── typescript/
│ │ ├── core/ # Group: core
│ │ │ ├── client.ts # Main client class
│ │ │ ├── index.ts # Exports
│ │ │ ├── enums.ts # Enum types
│ │ │ ├── errors.ts # Error classes
│ │ │ ├── http.ts # HTTP layer
│ │ │ ├── logger.ts # Logging
│ │ │ ├── retry.ts # Retry logic
│ │ │ ├── storage.ts # Storage utilities
│ │ │ ├── api-instance.ts # Singleton instance
│ │ │ ├── _utils/ # Fetchers, hooks, schemas
│ │ │ └── core__users/ # Tag-based subfolders
│ │ │ ├── client.ts
│ │ │ ├── models.ts
│ │ │ └── index.ts
│ │ ├── shop/ # Group: shop
│ │ └── content/ # Group: content
│ │
│ ├── python/
│ │ ├── core/
│ │ │ ├── __init__.py
│ │ │ ├── client.py # Async client
│ │ │ ├── sync_client.py # Sync client
│ │ │ ├── models.py # Pydantic models
│ │ │ └── enums.py # Enum classes
│ │ ├── shop/
│ │ └── content/
│ │
│ ├── go/
│ │ ├── core/
│ │ │ ├── client.go
│ │ │ ├── models.go
│ │ │ └── operations.go
│ │ ├── shop/
│ │ └── content/
│ │
│ ├── proto/
│ │ ├── core/
│ │ │ └── api__core/
│ │ │ ├── messages.proto
│ │ │ └── service.proto
│ │ ├── shop/
│ │ └── content/
│ │
│ └── swift/ # When --swift used
│ ├── core/
│ ├── shop/
│ └── content/
│
└── archive/ # Version history (when enabled)
└── 20250115_100000/OpenAPI Schemas
Each group gets its own OpenAPI schema URL:
/schema/core/schema/ # OpenAPI JSON
/schema/shop/schema/ # OpenAPI JSON
/schema/content/schema/ # OpenAPI JSONExamples
Microservices Architecture
Split API by service boundaries:
groups=[
OpenAPIGroupConfig(
name="auth",
apps=["authentication", "permissions", "oauth", "2fa"],
title="Authentication Service",
description="User authentication and 2FA"
),
OpenAPIGroupConfig(
name="trading",
apps=["wallets", "orders", "transactions"],
title="Trading Service",
description="Crypto trading operations"
),
OpenAPIGroupConfig(
name="market",
apps=["prices", "orderbooks", "tickers"],
title="Market Service",
description="Real-time market data"
),
]Team-Based Organization
Split API by team ownership:
groups=[
OpenAPIGroupConfig(
name="platform",
apps=["users", "api_keys", "webhooks"],
title="Platform API",
description="Core platform features (Platform Team)"
),
OpenAPIGroupConfig(
name="trading",
apps=["wallets", "orders", "positions"],
title="Trading API",
description="Trading features (Trading Team)"
),
OpenAPIGroupConfig(
name="data",
apps=["prices", "charts", "analytics"],
title="Data API",
description="Market data and analytics (Data Team)"
),
]Client Type Organization
Split API by client application:
groups=[
OpenAPIGroupConfig(
name="web",
apps=["dashboard", "portfolio", "settings"],
title="Web Application API",
description="Web trading dashboard"
),
OpenAPIGroupConfig(
name="mobile",
apps=["trading", "alerts", "watchlist"],
title="Mobile App API",
description="iOS and Android trading apps"
),
OpenAPIGroupConfig(
name="public",
apps=["prices", "tickers", "markets"],
title="Public API",
description="Public market data (no auth required)"
),
]Versioned APIs
Maintain multiple API versions:
groups=[
OpenAPIGroupConfig(
name="v1",
apps=["api.v1.wallets", "api.v1.orders"],
title="API v1 (Legacy)",
description="Legacy API - deprecated",
version="1.0.0"
),
OpenAPIGroupConfig(
name="v2",
apps=["api.v2.wallets", "api.v2.orders", "api.v2.positions"],
title="API v2 (Current)",
description="Current stable API",
version="2.0.0"
),
OpenAPIGroupConfig(
name="v3",
apps=["api.v3.wallets", "api.v3.orders"],
title="API v3 (Beta)",
description="Next generation API (beta)",
version="3.0.0-beta"
),
]Group Discovery
Automatic App Discovery
Groups automatically discover ViewSets and APIViews from included apps:
# users/api/views.py
from rest_framework import viewsets
from .models import User
from .serializers import UserSerializer
class UserViewSet(viewsets.ModelViewSet):
"""User management endpoints"""
queryset = User.objects.all()
serializer_class = UserSerializerWhen "users" is added to a group, all ViewSet endpoints are automatically included.
URL Patterns
Ensure apps are properly registered in URL configuration:
# users/urls.py
from rest_framework.routers import DefaultRouter
from .api.views import UserViewSet
router = DefaultRouter()
router.register('users', UserViewSet)
urlpatterns = router.urls# Main urls.py
from django.urls import path, include
urlpatterns = [
path('api/users/', include('users.urls')),
]Best Practices
1. Group Naming
Use clear, descriptive names:
✅ Good:
core- Core functionalityshop- E-commerce featuresanalytics- Reporting and analyticsadmin- Admin panelmobile- Mobile app
❌ Bad:
group1,group2- Not descriptiveapi_a,api_b- Unclear purposetest,dev- Environment names
2. Group Size
Aim for 5-10 apps per group:
✅ Good:
OpenAPIGroupConfig(
name="core",
apps=["users", "auth", "profiles", "settings", "notifications"]
)❌ Too Large:
OpenAPIGroupConfig(
name="everything",
apps=["users", "auth", "profiles", "products", "orders", "shipping",
"payments", "blog", "cms", "chat", "notifications", "analytics"]
# 12 apps - too many, split into multiple groups
)❌ Too Small:
OpenAPIGroupConfig(name="users", apps=["users"])
OpenAPIGroupConfig(name="auth", apps=["auth"])
OpenAPIGroupConfig(name="profiles", apps=["profiles"])
# These should be combined into one "core" group3. Logical Grouping
Group by domain logic, not technical layers:
✅ Good (Domain-Driven):
groups=[
OpenAPIGroupConfig(name="shop", apps=["products", "cart", "orders"]),
OpenAPIGroupConfig(name="billing", apps=["payments", "invoices", "subscriptions"]),
]❌ Bad (Technical Layers):
groups=[
OpenAPIGroupConfig(name="models", apps=["products", "users", "orders"]),
OpenAPIGroupConfig(name="views", apps=["api_views", "admin_views"]),
]4. Independent Groups
Keep groups independent with minimal cross-dependencies:
✅ Good:
- Core group (users, auth) - standalone
- Shop group (products, orders) - uses core
- Analytics group (reports, stats) - reads from all
❌ Bad:
- Group A depends on Group B
- Group B depends on Group C
- Group C depends on Group A (Circular dependencies make it hard to maintain)
Troubleshooting
Group Not Generating
Check app is installed in INSTALLED_APPS:
INSTALLED_APPS = [
# ...
'users',
'accounts',
]Verify URLs are registered:
python manage.py show_urls | grep usersRun schema validation:
python manage.py spectacular --format openapi --validate --file openapi.yamlEmpty Schema
Add ViewSets or APIViews to your app:
from rest_framework import viewsets
class MyViewSet(viewsets.ModelViewSet):
queryset = MyModel.objects.all()
serializer_class = MySerializerUse DRF decorators for function-based views:
from rest_framework.decorators import api_view
@api_view(['GET', 'POST'])
def my_endpoint(request):
passMultiple Apps in One Group
Merge related apps:
OpenAPIGroupConfig(
name="billing",
apps=[
"billing.api",
"payments.api",
"subscriptions.api",
"invoices.api"
],
title="Billing & Payments",
description="Complete billing system"
)Integration with Django-CFG
Automatic URL Configuration
Django-CFG automatically adds OpenAPI URLs for all groups:
# api/urls.py
from django_cfg import add_django_cfg_urls
urlpatterns = [
path("admin/", admin.site.urls),
]
# Adds /schema/{group}/ URLs automatically
urlpatterns = add_django_cfg_urls(urlpatterns)drf-spectacular Configuration
Django-CFG automatically configures drf-spectacular with optimized settings for client generation:
# Automatic configuration for proper model splitting
SPECTACULAR_SETTINGS = {
'COMPONENT_SPLIT_REQUEST': True, # Separate Request/Response models
'COMPONENT_SPLIT_PATCH': True, # Separate Patch models
# ... other settings auto-configured
}Group-specific title, description, and version are set per-group via OpenAPIGroupConfig.
Next Steps
- CLI Usage - Generate clients for your groups
- Generated Clients - Use generated clients
Group Testing
Access /schema/{group}/schema/ to download your group’s OpenAPI schema before generating clients.