使用 FLASK 将 REST API 与 Web 界面相结合的最佳实践

Posted

技术标签:

【中文标题】使用 FLASK 将 REST API 与 Web 界面相结合的最佳实践【英文标题】:Best practices to combine REST API with web interface using FLASK 【发布时间】:2014-01-14 22:06:16 【问题描述】:

我目前使用flask、sqlalchemy 和jinja2 构建了一个Web 应用程序。

为了获得正确的网络界面,我构建了如下视图:

@app.route('/mydata/', methods=['GET'])
@login_required
def mydata_list():
    # build data here...
    return render_template('mydata/index.html', data=data))

现在,如果我需要构建一个 REST API,我应该终止

return jsonify(data)

那么,如何处理以避免代码重复呢?在我的网址中添加?api=True,在我的视图中对其进行测试,然后返回适当的答案是一种好习惯吗?

【问题讨论】:

您是否考虑过使用 API 来获取 Web 界面的内容? 让我们将 HTML 端称为“网站”,将 JSON 端称为“API”(就我而言,仅返回 JSON 并不使其成为“REST API”)。没有“正确”的方式来区分这两者。有人会说,因为它们解决的是不同的问题,它们不会像你想象的那样相互交织(data 变量对于 HTML 和 JSON 可能不同)。您可以使用内容协商,或 URL 中的参数,或完全不同的 URL。没有“正确的方法”来区分这些问题。 【参考方案1】:

如果您想使用相同的端点来提供模板和 JSON 数据,您可以使用 request.is_xhr 测试这是否是 AJAX 请求。例如:

@app.route('/numbers/')
def numbers():
    data = [1, 2, 3]

    if request.is_xhr:
        return jsonify(data=data)

    return render_template('numbers.html', data=data)

【讨论】:

【参考方案2】:

确实没有正确或错误的方法来做到这一点,对于 Flask 更是如此,它是一个对开发人员施加如此少规则的框架。

如果你想听听我的意见,我认为对网站和 API 使用同一组视图函数会导致代码更难维护,因为两者之间存在一些显着差异,例如:

身份验证:对于 Web 与 API,这通常以非常不同的方式完成。 内容:对于 API,您只是返回数据,但对于网页,视图函数可能需要做更多工作并获取仅用于渲染模板的额外数据。 请求方法:API 使用比 Web 应用程序更多的 HTTP 请求方法。例如,要通过 API 删除资源,客户端通常会发送 DELETE 请求。在 Web 浏览器上运行的 Web 应用程序需要通过 GETPOST 请求完成所有操作。此外,POST 请求方法在 API 和 Web 应用中的用法有所不同。

我的建议是让 API 和 Web 应用程序的视图函数非常精简,并将应用程序的业务逻辑放在两组视图函数都可以调用的公共类中。

【讨论】:

以上是关于使用 FLASK 将 REST API 与 Web 界面相结合的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

将 Flask Restless API 连接到 Admin-on-rest (React)

flask编写RESTful API

使用 Flask-Security 作为 REST API 的一部分

通过 Flask-JWT REST API 使用 Flask-Security 角色

RESTful API 与 Web 服务 API

使用WebSocket扩展Flask REST API