在flask中支持多个API版本

时间:2015-03-01 15:52:08

标签: python flask

我开始使用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中,&#34;用户&#34; -endpoint被更改:

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

依旧......

查看this问题最简单的方法可能是这样的:

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

但我可以想象,每个新的API版本都会越难维护。因此,我想知道是否有更好的(=更容易维护和更好的结构化)方式来实现这个与Flask?

2 个答案:

答案 0 :(得分:68)

我是您所引用问题的接受答案的作者。我认为/<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版本所需的常用功能。例如,您可以使用辅助功能(未作为路线装饰)响应您在v1和v1.1中相同的/users路线。

每个API版本的routes.py定义路由,并在必要时调用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并减少更多自由,但理想情况下这种情况不会经常发生。

答案 1 :(得分:1)

如果仍然相关 我写了一个软件包来按版本管理端点 你可以在Git上找到它 https://github.com/itay-bardugo/flask_version