DRF cho 5 strategy, khác nhau ở nơi đặt version trong request:
URL path → /api/v1/posts/ Phổ biến nhất, debug dễ, cache friendly
Namespace → /api/v1/posts/ (URLconf namespace) Tách hẳn module per version
Accept header → Accept: ...; version=1.0 REST-ist nhất, URL sạch — nhưng khó debug
Host name → v1.api.example.com Khi version cần infrastructure khác
Query parameter → /api/posts/?version=1 Đơn giản, hợp prototypepython
# settings.py
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
'DEFAULT_VERSION': 'v1',
'ALLOWED_VERSIONS': ['v1', 'v2'],
}
# urls.py
urlpatterns = [
path('api/<version>/posts/', PostViewSet.as_view({'get': 'list'})),
]
# views.py
class PostViewSet(viewsets.ModelViewSet):
def get_serializer_class(self):
if self.request.version == 'v2':
return PostV2Serializer
return PostV1SerializerĐừng version chỉ vì có thể sau này sẽ thay đổi — chỉ version khi thật sự breaking.
- Chiến lược phổ biến hơn nhiều team đang dùng: giữ field cũ, thêm field mới, gắn header
Deprecation: ...; bump major chỉ khi không còn cách nào khác. - URL path versioning là default an toàn nhất cho team mới vì log, monitoring và cache key đều dễ tách riêng.
DRF supports five strategies that differ in where the version lives in the request:
URL path → /api/v1/posts/ Most common, easy to debug, cache-friendly
Namespace → /api/v1/posts/ (URLconf namespace) Separate modules per version
Accept header → Accept: ...; version=1.0 Most REST-pure, clean URLs — but hard to debug
Host name → v1.api.example.com When versions need different infra
Query parameter → /api/posts/?version=1 Simple, fits prototypespython
# settings.py
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
'DEFAULT_VERSION': 'v1',
'ALLOWED_VERSIONS': ['v1', 'v2'],
}
# urls.py
urlpatterns = [
path('api/<version>/posts/', PostViewSet.as_view({'get': 'list'})),
]
# views.py
class PostViewSet(viewsets.ModelViewSet):
def get_serializer_class(self):
if self.request.version == 'v2':
return PostV2Serializer
return PostV1SerializerPitfall: Do not version just because something might change later — version only on real breaking changes.
- A more popular strategy: keep old fields + add new fields + send a
Deprecation: ...header; bump major only when there is no other way. - URL path versioning is the safest default for new teams — logs, monitoring, cache keys all separate cleanly.