更新:
版本控制现在得到了很好的支持。
你提供的链接中有一些答案:
我们认为,在 URL 中加入版本号是实用且有用的。这可以让用户一目了然地知道正在使用的版本。我们将 /foo 别名为 /foo/(最新版本),以便于使用、缩短 URL 并使其更加规范,如所接受的答案所建议的那样。
永远保持向后兼容通常是代价高昂和/或非常困难的。我们更喜欢提前公告弃用、重定向等方式,以及文档和其他机制。
因此,我们采用了这种方法,并允许客户端在请求头(X-Version)中指定版本,以下是我们的实现方式:
API 应用程序内部结构:
.
├── __init__.py
├── middlewares.py
├── urls.py
├── v1
│ ├── __init__.py
│ ├── account
│ │ ├── __init__.py
│ │ ├── serializers.py
│ │ └── views.py
│ └── urls.py
└── v2
├── __init__.py
├── account
│ ├── __init__.py
│ ├── serializers.py
│ └── views.py
└── urls.py
项目 urls.py:
url(r'^api/', include('project.api.urls', namespace='api')),
API 应用程序级别的 urls.py:
from django.conf.urls import *
urlpatterns = patterns('',
url(r'', include('project.api.v2.urls', namespace='default')),
url(r'^v1/', include('project.api.v1.urls', namespace='v1')),
)
版本层级urls.py
from django.conf.urls import *
from .account import views as account_views
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('account', account_views.AccountView)
router.register('myaccount', account_views.MyAccountView)
urlpatterns = router.urls
创建一个中间件,通过更改path_info来切换到正确的代码,请注意,项目级别urls中定义的命名空间('api')不够灵活,需要在中间件中进行知晓。
from django.core.urlresolvers import resolve
from django.core.urlresolvers import reverse
class VersionSwitch(object):
def process_request(self, request):
r = resolve(request.path_info)
version = request.META.get('HTTP_X_VERSION', False)
if r.namespace.startswith('api:') and version:
old_version = r.namespace.split(':')[-1]
request.path_info = reverse('{}:{}'.format(r.namespace.replace(old_version, version), r.url_name), args=r.args, kwargs=r.kwargs)
示例网址:
curl -H "X-Version: v1" http://your.domain:8000/api/myaccount/