我正在使用Flask构建ReST / JSON API。我希望我的所有响应都是JSON,即使它们是错误响应。
我已经让我的应用程序返回统一的JSON响应,以便成功运行和大多数错误。这是我的代码的相关部分:
from flask import Flask, jsonify
from werkzeug import exceptions
app = Flask(__name__)
def make_json_response(status, message, content):
"""Function to generate uniform JSON responses across the API"""
response = {
"api_version": __version__,
"content": content, # The data the API is supposed to return
"message": message, # Content description, error message, etc.
"request_id": g.get("request_id", None),
"status": status, # HTTP Status
}
return jsonify(response), status
def json_error_handler(error=exceptions.InternalServerError, message=None):
"""Makes JSON error messages. By default, Flask will return HTML error
messages, but we want this API to return valid JSON even on errors."""
return make_json_response(
status=error.code, message=message or error.description, content=None)
# Registering JSON error handlers for each HTTP error that we might reasonably throw.
# Covers 400, 401, 403, 404, 405, 406, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 422, 428, 429, 431, 500, 501, 502, 503, 504, 505
for error_class in exceptions.default_exceptions.values():
app.register_error_handler(error_class, json_error_handler)
所以这一切都在发挥作用。但是,未解决300-3XX响应。据我所知,重定向错误不是raise
d,与其他错误相同。例如,当我的代码中存在错误时,500可能随时出现,但300s是路由决定,并且在我的代码到达之前发生。
Flask非常有用地生成自动重定向响应。例如,如果用户尝试获取/jobs
,但真实路径为/jobs/
,则Flask将使用重定向进行回复,而不会在我的结尾处执行其他工作:
$ curl -i https://api.example.com/jobs
HTTP/1.1 301 MOVED PERMANENTLY
Server: gunicorn/19.6.0
Date: Thu, 01 Jun 2017 14:40:18 GMT
X-Cnection: close
Content-Type: text/html; charset=utf-8
Location: http://api.example.com/jobs/
Content-Length: 295
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>Redirecting...</title>
<h1>Redirecting...</h1>
<p>You should be redirected automatically to target URL: <a href="http://api.example.com/jobs/">http://api.example.com/jobs/</a>. If not click the link.
这是理想的行为。唯一的问题是生成的响应不符合API其余响应所使用的JSON响应模式。这可能会导致期望JSON响应的客户端爆炸。 (现在,任何容易发生问题的客户都应该真正知道正确的URI,但我仍然希望我的API响应统一且有用。)
据我所知,在幕后,Flask使用werkzeug.utils.redirect生成重定向,但我没有看到一种明显的方法将我自己的重定向功能修补到我的Flask应用程序中。
有没有办法更改自动生成的Flask重定向响应?