Skip to Content

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

ParameterTypeDefaultRequiredDescription
namestr-YesUnique group identifier. Lowercase, no spaces. Used in URLs (/schema/{name}/) and file paths (openapi/{name}/)
appsList[str]-YesDjango app labels to include. Supports wildcards (e.g., "django_cfg.*")
titlestr-YesHuman-readable title. Shown in Swagger UI and Redoc
descriptionstr""NoDetailed explanation of group purpose
versionstr"v1"NoAPI version (semantic versioning recommended)
auth_requiredboolFalseNoWhether 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 JSON

Examples

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 = UserSerializer

When "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 functionality
  • shop - E-commerce features
  • analytics - Reporting and analytics
  • admin - Admin panel
  • mobile - Mobile app

Bad:

  • group1, group2 - Not descriptive
  • api_a, api_b - Unclear purpose
  • test, 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" group

3. 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 users

Run schema validation:

python manage.py spectacular --format openapi --validate --file openapi.yaml

Empty Schema

Add ViewSets or APIViews to your app:

from rest_framework import viewsets class MyViewSet(viewsets.ModelViewSet): queryset = MyModel.objects.all() serializer_class = MySerializer

Use DRF decorators for function-based views:

from rest_framework.decorators import api_view @api_view(['GET', 'POST']) def my_endpoint(request): pass

Multiple 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

Group Testing

Access /schema/{group}/schema/ to download your group’s OpenAPI schema before generating clients.

Last updated on