【问题标题】:How to get rid of the version information in API url in tastypie django?如何摆脱tastepie django中API url中的版本信息?
【发布时间】:2012-10-18 18:56:57
【问题描述】:

我正在为使用 Tastypie 和 Django 的应用程序创建基于 REST 的 API。问题是 Tastypie 中的默认 API url 包含 url 模式中的版本信息,即

http://lx:3001/api/v1/vservers/?username=someuser&api_key=someapikey

我希望我的网址不受 API 版本信息的影响,如下所示:

http://lx:3001/api/vservers/?username=someuser&api_key=someapikey

urls.py

v1_api = Api()
v1_api.api_name = ''
v1_api.register(UserResource())
...
url(r'^api/', include(v1_api.urls)),

我仍然用空字符串覆盖 api_name

http://lx:3001/api/vservers/?username=someuser&api_key=someapikey 不起作用。

我怎样才能完全摆脱版本信息?

谢谢..

【问题讨论】:

  • 这不是一个好主意。您应该始终对您的 API 进行版本控制。如果您将来更改某些内容,您会后悔这个决定。
  • 我同意。这是一个功能。当您(不可避免地)需要添加或更改 API 时,对 API 进行版本控制可以让您保持向后兼容。尚未更新其调用的客户端仍然可以运行,而新客户端可以利用新的 API 功能。
  • 我的想法是在客户不知道版本信息的情况下,随时将客户引导至最新版本的 API。
  • 非常糟糕的主意,他们的应用程序会崩溃。考虑一下当您发布新 API 并且他们的应用程序开始使用它而无需进行必要更改时的情况。
  • 感谢您的澄清。我将版本信息保留在 url 中。

标签: django api rest tastypie


【解决方案1】:

子类 Api 并覆盖 urls 以删除所有与 api_name 相关的位:

class MyApi(Api):
    @property
    def urls(self):
        """
        Provides URLconf details for the ``Api`` and all registered
        ``Resources`` beneath it.
        """
        pattern_list = [
            url(r"^%s$" % trailing_slash(), self.wrap_view('top_level'), name="api_top_level"),
        ]

        for name in sorted(self._registry.keys()):
            pattern_list.append((r"^/", include(self._registry[name].urls)))

        urlpatterns = self.override_urls() + patterns('',
            *pattern_list
        )
        return urlpatterns

【讨论】:

  • 感谢 dokkaebi 提供代码 sn-p。现在将在 REST url 中保留版本信息..
  • 可能是最好的。当您决定更改 API 时,这两个小角色可以拯救世界。出于好奇,这个 sn-p 有效吗?
  • 是的,我一直在观看一些演讲,关于版本控制的争论很大。不过,争论的焦点是,如果您的 API 真的是 REST 而不仅仅是 JSON HTTP API,那么您不需要版本,因为响应会提供指向其他数据的链接...
【解决方案2】:

虽然tastepie 提供api_name 是可选的,但如果没有提供一个简单的默认api_name"v1"。可以通过继承Api 并覆盖api.py 中的urls 属性以独立于api_name 来修改此行为。然而,为了实现所需的 URLconf,@dokkaebi 的解决方案仍有一个值得注意的更正:

pattern_list.append((r"^/", include(self._registry[name].urls)))

应该改为:

pattern_list.append((r'', include(self._registry[name].urls)))

为了避免可怕的// 将您的客户引导至

http://lx:3001/api//vservers/?username=someuser&api_key=someapikey 代替 http://lx:3001/api/vservers/?username=someuser&api_key=someapikey 符合预期。

为方便起见,我在下面包含了修改后的代码。

解决方案

class MyApi(Api):
"""
An API subclass that circumvents api_name versioning.
"""
@property
def urls(self):
    """
    Provides URLconf details for the ``Api`` and all registered
    ``Resources`` beneath it.
    """
    pattern_list = [
        url(r"^%s$" % trailing_slash(), self.wrap_view('top_level'), name="api_top_level"),
    ]

    for name in sorted(self._registry.keys()):
        pattern_list.append((r'', include(self._registry[name].urls)))

    urlpatterns = self.override_urls() + patterns('',
        *pattern_list
    )
    return urlpatterns

约定

Django 的核心理念之一是 URL 应该是漂亮的;干净、优雅的 URL 方案是任何高质量 Web 应用程序的重要细节。关于这种方法的有效性,使用自定义请求标头或接受标头将完成版本控制工作,而不会使方案与(主观上)丑陋的 v1/.这并不是说 URL 版本控制策略没有任何警告。但是,它的实施速度很快,而且反应可预测。

【讨论】:

    猜你喜欢
    • 2012-03-02
    • 1970-01-01
    • 1970-01-01
    • 2020-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-16
    • 1970-01-01
    相关资源
    最近更新 更多