Skip to content

Schemas & OpenAPI

API schemas are a useful tool that allow for a range of use cases, including generating reference documentation, or driving dynamic client libraries that can interact with your API.

WARNING

Deprecation Notice: DRF's built-in support for generating OpenAPI schemas is deprecated in favor of 3rd party packages. The built-in support will be moved into a separate package and subsequently retired. We recommend using drf-spectacular.

However, understanding the built-in system is still helpful as many concepts carry over. DRF natively supports OpenAPI (formerly Swagger), which is a widely adopted standard for describing APIs.

Schema Generation Process

Before generating schemas, it's important to understand the components involved. Schema generation in DRF has several moving parts:

  1. SchemaGenerator: The top-level class responsible for walking your configured URL patterns, finding APIView subclasses, enquiring for their schema representation and compiling the final schema object.
  2. AutoSchema: Encapsulates all the details necessary for per-view schema introspection. It is attached to each view via the schema attribute.
  3. generateschema: A management command that allows you to generate a static schema offline.
  4. SchemaView: A view that dynamically generates and serves your schema.

Generating an OpenAPI Schema

::: Prerequisites To generate schemas, you must install additional dependencies: pip install pyyaml uritemplate inflection.

  • pyyaml: Generates schema into YAML format.
  • uritemplate: Gets parameters in path.
  • inflection: Pluralizes operations appropriately. :::

Static vs Dynamic Generation

You can generate your schema statically (to a file) or dynamically (via an endpoint). Generating statically is often preferred for CI/CD pipelines, while dynamic generation is useful if your schema depends on database values.

bash
# Generate a YAML file (default)
python manage.py generateschema --file openapi-schema.yml

# Or explicitly format as JSON
python manage.py generateschema > schema.json --format json
python
from django.urls import path
from rest_framework.schemas import get_schema_view

# In your urls.py
urlpatterns = [
    path('openapi/', get_schema_view(
        title="Your Project",
        description="API for all things …",
        version="1.0.0"
    ), name='openapi-schema'),
]

When a user visits /openapi/, they will receive a YAML (or JSON, based on negotiation) representation of the OpenAPI schema. By default, get_schema_view() uses settings.DEFAULT_AUTHENTICATION_CLASSES and settings.DEFAULT_PERMISSION_CLASSES.

Customizing Schema Generation

You can customize how individual views generate their schema operations by setting the schema attribute on a view to an instance of AutoSchema (or a subclass).

python
from rest_framework.views import APIView
from rest_framework.schemas.openapi import AutoSchema

class CustomView(APIView):
    # Customize the schema for this specific view
    schema = AutoSchema(
        tags=['Users'],
        operation_id_base='CustomUser',
    )

TIP

Excluding Views: To entirely exclude a view from the schema, you can set its schema attribute to None. This is useful for internal endpoints or administrative views you don't want exposed in public documentation.

python
class ExcludedView(APIView):
    schema = None

While DRF includes basic OpenAPI support, you should use third-party packages for a fully-featured Swagger UI or ReDoc interface, especially given the deprecation of the built-in generator.

A popular and highly recommended choice is drf-spectacular:

  1. Install it: pip install drf-spectacular
  2. Add to INSTALLED_APPS: 'drf_spectacular'
  3. Set it as the default schema class in settings:
python
# settings.py
REST_FRAMEWORK = {
    # Replaces the default AutoSchema with drf-spectacular's implementation
    'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',
}

Then you can use it to serve Swagger UI or ReDoc directly:

python
from django.urls import path
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView

urlpatterns = [
    # The actual schema endpoint
    path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
    # The Swagger UI endpoint that consumes the schema
    path('api/docs/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
]