---
title: Group Configuration
sidebar_position: 3
keywords:
  - django-cfg groups
  - api groups
  - openapi groups
description: Configure API generation groups for organizing large APIs. Manage multiple API clients with group-specific settings and separate OpenAPI schemas.
---

# 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:

```python
# 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:

```python
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:**

```python
# 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:

```python
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:

```python
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:

```python
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:

```python
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:

```python
# 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:

```python
# users/urls.py
from rest_framework.routers import DefaultRouter
from .api.views import UserViewSet

router = DefaultRouter()
router.register('users', UserViewSet)

urlpatterns = router.urls
```

```python
# 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:**
```python
OpenAPIGroupConfig(
    name="core",
    apps=["users", "auth", "profiles", "settings", "notifications"]
)
```

❌ **Too Large:**
```python
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:**
```python
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):**
```python
groups=[
    OpenAPIGroupConfig(name="shop", apps=["products", "cart", "orders"]),
    OpenAPIGroupConfig(name="billing", apps=["payments", "invoices", "subscriptions"]),
]
```

❌ **Bad (Technical Layers):**
```python
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`:
```python
INSTALLED_APPS = [
    # ...
    'users',
    'accounts',
]
```

**Verify URLs are registered:**
```bash
python manage.py show_urls | grep users
```

**Run schema validation:**
```bash
python manage.py spectacular --format openapi --validate --file openapi.yaml
```

### Empty Schema

**Add ViewSets or APIViews** to your app:
```python
from rest_framework import viewsets

class MyViewSet(viewsets.ModelViewSet):
    queryset = MyModel.objects.all()
    serializer_class = MySerializer
```

**Use DRF decorators** for function-based views:
```python
from rest_framework.decorators import api_view

@api_view(['GET', 'POST'])
def my_endpoint(request):
    pass
```

### Multiple Apps in One Group

Merge related apps:

```python
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:

```python
# 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:

```python
# 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](./cli-usage)** - Generate clients for your groups
- **[Generated Clients](./generated-clients)** - Use generated clients
- **[Django Client Module](../modules/django-client/overview)** - Deep dive


<Callout type="info">
**Group Testing**

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

</Callout>
