Реализация исключений API
Очень часто RESTful API реализуются поверх Flask. Одно из первых, с чем сталкиваются разработчики, — это осознание того, что встроенные исключения недостаточно выразительны для API, а тип содержимого text/html, который они генерируют, не очень полезен для потребителей API.
Лучшим решением, чем использование abort для сигнализации об ошибках при некорректном использовании API, является реализация собственного типа исключения и установка обработчика ошибок для него, который генерирует ошибки в формате, ожидаемом пользователем.
Простой класс исключений
Основная идея заключается в представлении нового исключения, которое может принимать правильное удобочитаемое сообщение, код состояния для ошибки и некоторые необязательные данные, чтобы предоставить дополнительный контекст для ошибки.
Вот простой пример:
from flask import jsonify
class InvalidUsage(Exception):
status_code = 400
def __init__(self, message, status_code=None, payload=None):
Exception.__init__(self)
self.message = message
if status_code is not None:
self.status_code = status_code
self.payload = payload
def to_dict(self):
rv = dict(self.payload or ())
rv['message'] = self.message
return rv
Теперь представление может вызвать это исключение с сообщением об ошибке. Кроме того, дополнительные данные могут быть предоставлены в виде словаря через параметр payload.
Регистрация обработчика ошибок
На этом этапе представления могут вызвать эту ошибку, но это сразу приведет к внутренней ошибке сервера. Причина в том, что для этого класса ошибок не зарегистрирован обработчик. Однако добавить его легко:
@app.errorhandler(InvalidUsage)
def handle_invalid_usage(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response
Использование в представлениях
Вот как представление может использовать эту функциональность:
@app.route('/foo')
def get_foo():
raise InvalidUsage('This view is gone', status_code=410)
© 2007–2020 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/0.12.x/patterns/apierrors/