API Versioning Strategies0%

API Versioning Strategies

Beginner12 min read•Updated: Jul 11, 2026
Study MaterialsCheatsheet

DRF API Versioning Strategies

APIs are contracts with client applications. As business requirements change, you will inevitably introduce breaking changes—modifying field names, altering response shapes, or removing deprecated endpoints. Without API Versioning, releasing breaking changes breaks legacy mobile apps and third-party integrations. Django REST Framework provides five built-in versioning schemes to manage API evolution gracefully.


1. The Five DRF Versioning Schemes

Output
1. URLPathVersioning (Industry Standard):
https://api.enterprise.com/v1/articles/
https://api.enterprise.com/v2/articles/
 
2. NamespaceVersioning:
Routed via Django URLconf namespaces ('v1:articles', 'v2:articles')
 
3. QueryParameterVersioning:
https://api.enterprise.com/articles/?version=v2
 
4. AcceptHeaderVersioning:
GET /articles/ Header: Accept: application/json; version=2.0
 
5. HostNameVersioning:
https://v1.api.enterprise.com/articles/
https://v2.api.enterprise.com/articles/

URLPathVersioning is the most popular, explicit, and cache-friendly versioning pattern in enterprise software:

Python
# config/settings.py
REST_FRAMEWORK = {
# 1. Declare versioning scheme
"DEFAULT_VERSIONING_CLASS": "rest_framework.versioning.URLPathVersioning",
# 2. Default fallback version if unspecified
"DEFAULT_VERSION": "v1",
# 3. Whitelist permitted versions
"ALLOWED_VERSIONS": ["v1", "v2"],
# 4. URL parameter name
"VERSION_PARAM": "version",
}

3. Configuring urls.py with Version Parameter

Use the <version> path parameter in root routing:

Python
# config/urls.py
from django.urls import path, re_path, include
 
urlpatterns = [
# Captures /api/v1/ or /api/v2/ into request.version
re_path(r"^api/(?P<version>(v1|v2))/", include("api.urls")),
]

4. Adapting Views & Serializers Based on Version

In your views and serializers, inspect request.version to alter behavior dynamically:

Python
# api/views.py
from rest_framework.viewsets import ModelViewSet
from .models import Article
from .serializers_v1 import ArticleSerializerV1
from .serializers_v2 import ArticleSerializerV2
 
class ArticleViewSet(ModelViewSet):
queryset = Article.objects.all()
 
def get_serializer_class(self):
# Serve different serializer schemas based on API version!
if self.request.version == "v2":
return ArticleSerializerV2
return ArticleSerializerV1

Serializer Schema Evolution:

  • v1 Response: Returns flat attributes: {"author_name": "Dr. Sumit"}.
  • v2 Response: Returns structured nested object: {"author": {"id": 1, "name": "Dr. Sumit", "avatar": "..."}}.

5. Deprecation Policy & Sunset Headers

When retiring an API version, inform clients ahead of time using the standard HTTP Sunset header:

Python
# In v1 middleware or response hook:
response["Sunset"] = "Wed, 01 Jan 2027 00:00:00 GMT"
response["Link"] = '<https://api.enterprise.com/docs/v2-migration>; rel="sunset"'

Interactive Quiz

Practice Quiz

Question 1
What is the primary purpose of versioning a REST API?
Question 2
Why is URLPathVersioning (e.g. /api/v1/resource/) widely preferred over Header or Query Parameter versioning?
Question 3
How does a DRF view access the active requested API version string?
Question 4
What does ALLOWED_VERSIONS = ["v1", "v2"] configure in DRF settings?
Question 5
What standard HTTP response header communicates the scheduled retirement date of an older API version?
Next Lesson

Rate Limiting & Throttling

Continue learning with hands-on practice, examples, and exercises in the upcoming topic.

Related Lessons

Practice Quiz

Test your understanding of this lesson with 5 questions. Each question has one correct answer.

PrevNext