Django rest框架:api版本控制

2024-06-07 15:49:53 发布

您现在位置:Python中文网/ 问答频道 /正文

因此,在google上搜索它,似乎普遍的共识是在resturi中嵌入版本号是一种不好的做法,也是一个不好的主意。

即使如此,也有强烈的支持者支持这一点。
e、 克Best practices for API versioning?

我的问题是如何在django rest框架中使用accept header/content协商来实现这一点。

它看起来像框架中的内容协商,
http://django-rest-framework.org/api-guide/content-negotiation/ 已配置为基于接受的MIME类型自动返回预期值。如果我开始对自定义类型使用Accept头,我将失去这个框架的好处。

有没有更好的方法在框架中实现这一点?


Tags: django框架rest类型for版本号googlecontent
2条回答

一种方法是将版本控制指定为媒体类型的一部分。

这就是GitHubcurrently do for their API

您还可以在accept头中包含媒体类型参数,例如Accept: application/json; version=beta,它将与JSONRenderer成功匹配。然后,可以根据接受的媒体类型对视图进行编码,使其行为有所不同,请参见here

在api中有很多不同的版本控制模式,我不认为对正确的方法有什么共识,但这是一个合理的可能性。


2015年1月更新:3.1.0版将提供更好的版本控制支持。请参阅[此请求]

更新2015年3月:版本控制API的文档are now available

https://github.com/tomchristie/django-rest-framework/pull/2285)了解更多详细信息。

更新:

versioning现在得到了正确的支持。


您的链接提供了一些答案:

We found it practical and useful to put the version in the URL. It makes it easy to tell what you're using at a glance. We do alias /foo to /foo/(latest versions) for ease of use, shorter / cleaner URLs, etc, as the accepted answer suggests. Keeping backwards compatibility forever is often cost-prohibitive and/or very difficult. We prefer to give advanced notice of deprecation, redirects like suggested here, docs, and other mechanisms.

所以我们采用了这种方法,并允许客户机在请求头(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

项目url.py:

url(r'^api/', include('project.api.urls', namespace='api')),

api应用程序级URL.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')),
)

版本级url.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

创建中间件以通过更改路径信息切换到正确的代码,请注意,在项目级URL中定义的命名空间(“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)

示例url:

curl -H "X-Version: v1" http://your.domain:8000/api/myaccount/

相关问题 更多 >

    热门问题