当前位置: 首页 > 面试题库 >

在Flask中支持多个API版本

万俟华辉
2023-03-14
问题内容

我开始使用Flask和Python设计一种RESTful Web服务,我想知道如何在同一项目中支持多个API版本。我正在考虑将请求的API版本放在这样的URL中:

/myapp/v1/Users

一段时间后,我想在API版本1.1中添加另一个端点,并保留v1中所有未更改的内容:

/myapp/v1.1/Users   <= Same as in v1
/myapp/v1.1/Books

在v2中,“用户”端点已更改:

/myapp/v2/Users   <= Changed in v2
/myapp/v2/Books   <= Same as in v1.1

等等…

看着这个问题,最简单的方法可能是这样的:

@app.route('/<version>/users')
def users(version):
    # do something
    return jsonify(response)

但是我可以想象每个新的API版本都将很难维护它。因此,我想知道Flask是否有更好的方法(更易于维护和结构化)来实现这一目标?


问题答案:

我是你所提及问题的被接受答案的作者。我认为这种/<version>/users方法不是你所说的那么有效。如果你必须管理三个或四个不同的版本,则最终将得到意大利面条代码。

我在那里提出的Nginx想法更好,但缺点是必须托管两个单独的应用程序。那时,我错过了提及第三种替代方法,即为每个API版本使用一个蓝图。例如,考虑以下应用程序结构(为清晰起见,已进行了极大简化):

my_project
+-- api/
    +-- v1/
        +-- __init__.py
        +-- routes.py
    +-- v1_1/
        +-- __init__.py
        +-- routes.py
    +-- v2/
        +-- __init__.py
        +-- routes.py
    +-- __init__.py
    +-- common.py

在这里,你可以api/common.py实现所有API版本所需的通用功能。例如,你可以具有一个辅助功能(未装饰为路线),该功能可以响应你/users在v1和v1.1中相同的路线。

routes.py每个API版本定义的路由,并在必要时调用放入common.py功能,以避免重复的逻辑。例如,你的v1和v1.1 routes.py可以具有:

from api import common

@api.route('/users')
def get_users():
    return common.get_users()

注意api.route。这api是一个蓝图。将每个API版本实现为蓝图有助于将所有内容与正确的版本化URL结合在一起。以下是将API蓝图导入到应用程序实例中的示例应用程序设置代码:

from api.v1 import api as api_v1
from api.v1_1 import api as api_v1_1
from api.v2 import api as api_v2

app.register_blueprint(api_v1, url_prefix='/v1')
app.register_blueprint(api_v1_1, url_prefix='/v1.1')
app.register_blueprint(api_v2, url_prefix='/v2')

这种结构非常好,因为它使所有API版本保持独立,但它们由同一应用程序提供。另外一个好处是,当需要停止支持v1时,只需删除该register_blueprint版本的调用,v1从源中删除该软件包即可。

现在,说了这么多,你应该真正以最小的方式来设计API,以最大程度地减少版本修订的风险。考虑到添加新路由不需要新的API版本,最好用新路由扩展API。有时可以以不影响旧客户端的方式设计现有路由的更改。有时候,修改API的痛苦会较小,而拥有更改事物的更多自由,但是理想情况下,这种情况不会经常发生。



 类似资料:
  • 我使用JUnit生成协议和Pacts maven插件将协议发布到协议代理中。我正在使用下面的插件配置 当Consumenr协议在broker中上传时,我只能看到2.0版的consumer协议的单个条目。Eirlier我已经上传了1.0版本Eirlier,它没有出现在UI中。有没有办法在HAL浏览器中看到多个版本的同一提供者协议,并通过Https get请求获得不同版本的协议?目前,我只得到最新的消

  • 问题内容: 在1.6版的android android.jar中访问联系人具有People.CONTENT_URI来调用与联系人相关的信息,而在更高版本中,我们需要对RawContacts.CONTENT_URI具有api支持。 例如,访问日历也是如此,因为在Android 2.2中更改了其URI。 是否有最佳实践来管理所有不同的更改,而无需添加其他应用程序或为每个版本的更改单独构建? 问题答案:

  • 问题内容: 我正在这样写我的文档测试: 这对于Python 2.5、2.6和2.7版本可以正常工作,但对于Python 3则失败,并出现以下错误: 问题是,如果我这样编写我的doctest: 它们仅适用于Python3,而在Python2版本上无效。我的问题是如何使其跨版本兼容? 问题答案: 我在IPython中遇到了与doctests相同的问题。没有整洁的解决方案,但是我将所有前缀都包装在中,即

  • 本文向大家介绍iOS 支持多个域,包括了iOS 支持多个域的使用技巧和注意事项,需要的朋友参考一下 示例 应用程序支持的每个域都需要提供其自己的apple-app-site-association文件。如果每个域提供的内容不同,则文件的内容也将更改以支持相应的路径。否则,可以使用相同的文件,但是需要在每个受支持的域中访问该文件。

  • 我们有一个越来越多的招摇过市的API/openAPI,用于记录我们喜欢记录的路径或参数(可能还有定义)上的更改,因为该API的哪个版本可用。 swagger规范知道字段,但是在或上,我找不到引用此版本的内容。 可能是以x开头的供应商扩展 类似于x,因为可能会有帮助。至少使用它们验证不会失败。 但是这个用例是否有任何现有的实现?

  • 本文向大家介绍SpringBoot实现API接口多版本支持的示例代码,包括了SpringBoot实现API接口多版本支持的示例代码的使用技巧和注意事项,需要的朋友参考一下 一、简介 产品迭代过程中,同一个接口可能同时存在多个版本,不同版本的接口URL、参数相同,可能就是内部逻辑不同。尤其是在同一接口需要同时支持旧版本和新版本的情况下,比如APP发布新版本了,有的用户可能不选择升级,这是后接口的版本