Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Какие знаю группы ответов HTTP?
HTTP статус-коды разделены на пять групп (классов) в зависимости от первой цифры. Это стандартизированная система (RFC 7231), которая позволяет клиентам сразу понять категорию ответа.
1xx — Информационные ответы (Information)
Сервер информирует об уровне выполнения запроса. Это служебные коды, которые редко встречаются в обычных приложениях.
# 100 Continue
# Клиент может продолжить отправку тела запроса
# Используется для очень больших файлов
# 101 Switching Protocols
# Переключение протокола (HTTP -> WebSocket)
from flask import Flask
from flask_socketio import SocketIO
app = Flask(__name__)
socketio = SocketIO(app)
# WebSocket инициируется через 101 Switching Protocols
# 102 Processing (WebDAV)
# Сервер обрабатывает запрос, но ещё не готов ответить
# Нужно дождаться финального ответа
# 103 Early Hints
# Отправка подсказок для предварительной загрузки ресурсов
2xx — Успешные ответы (Success)
Запрос был успешно получен, понят и обработан.
from flask import Flask, jsonify, request
app = Flask(__name__)
# 200 OK
# Стандартный успешный ответ
@app.route('/api/users/<int:user_id>')
def get_user(user_id):
user = {'id': user_id, 'name': 'Alice'}
return jsonify(user) # 200 по умолчанию
# 201 Created
# Ресурс успешно создан (POST, PUT)
@app.route('/api/users', methods=['POST'])
def create_user():
data = request.get_json()
new_user = {'id': 123, **data}
return jsonify(new_user), 201 # 201 Created
# 202 Accepted
# Запрос принят, но ещё не обработан
# Используется для асинхронных операций
@app.route('/api/tasks', methods=['POST'])
def create_task():
# Добавляем задачу в очередь Celery
task_id = celery_app.send_task('process_data').id
return jsonify({'task_id': task_id}), 202 # Accepted
# 204 No Content
# Успешный ответ, но нет тела (DELETE, PATCH без возврата)
@app.route('/api/users/<int:user_id>', methods=['DELETE'])
def delete_user(user_id):
# Удаляем пользователя
return '', 204 # No Content
# 206 Partial Content
# Частичный контент (для Range requests, видео-плеер)
@app.route('/api/file/<file_id>')
def get_file(file_id):
if 'Range' in request.headers:
# Клиент просит только часть файла
return send_file_partial(file_id), 206
return send_file(file_id), 200
3xx — Перенаправления (Redirection)
Дополнительные действия нужны для завершения запроса (обычно перенаправление).
from flask import Flask, redirect, url_for
from urllib.parse import urljoin
app = Flask(__name__)
# 300 Multiple Choices
# Несколько вариантов ответа (редко используется)
# 301 Moved Permanently
# Ресурс постоянно перемещён на другой URL
@app.route('/old-url')
def old_endpoint():
return redirect('https://example.com/new-url', code=301)
# 302 Found (временное перенаправление)
@app.route('/login-required')
def check_auth():
if not is_authenticated():
return redirect('/login', code=302)
return 'Protected content'
# 303 See Other
# Ответ на POST может быть получен через GET (Post-Redirect-Get паттерн)
@app.route('/submit-form', methods=['POST'])
def submit_form():
# Обрабатываем форму
save_data(request.get_json())
# Перенаправляем на результат через GET
return redirect('/result', code=303)
# 304 Not Modified
# Клиентский кеш всё ещё актуален (conditional request)
@app.route('/api/data')
def get_data():
if 'If-None-Match' in request.headers:
etag = calculate_etag(data)
if request.headers['If-None-Match'] == etag:
return '', 304 # Не модифицировано
return jsonify(data), 200
# 307 Temporary Redirect
# Временное перенаправление, но сохранить метод (GET остаётся GET)
# 308 Permanent Redirect
# Постоянное перенаправление, но сохранить метод
@app.route('/api/v1/users')
def old_api():
return redirect('/api/v2/users', code=308)
4xx — Ошибки клиента (Client Errors)
Сервер получил некорректный запрос или отказывает в доступе.
from flask import Flask, jsonify
from werkzeug.exceptions import BadRequest, NotFound, Forbidden
app = Flask(__name__)
# 400 Bad Request
# Синтаксически неверный запрос
@app.route('/api/users', methods=['POST'])
def create_user():
data = request.get_json()
if not data:
return jsonify({'error': 'Invalid JSON'}), 400
# 401 Unauthorized
# Требуется аутентификация
@app.route('/api/me')
def get_profile():
if 'Authorization' not in request.headers:
return jsonify({'error': 'Missing token'}), 401
return get_user_profile()
# 403 Forbidden
# Аутентифицирован, но нет прав доступа
@app.route('/api/admin/users')
def admin_users():
if not current_user.is_admin:
return jsonify({'error': 'Admin access required'}), 403
return get_all_users()
# 404 Not Found
# Ресурс не найден
@app.route('/api/users/<int:user_id>')
def get_user(user_id):
user = User.query.get(user_id)
if not user:
return jsonify({'error': 'User not found'}), 404
return jsonify(user.to_dict())
# 405 Method Not Allowed
# Метод HTTP не разрешён для этого ресурса
# Автоматически генерируется Flask
# 409 Conflict
# Запрос конфликтует с текущим состоянием (версионирование, дубликат)
@app.route('/api/users', methods=['POST'])
def create_user():
email = request.get_json()['email']
if User.query.filter_by(email=email).exists():
return jsonify({'error': 'Email already exists'}), 409
return create_new_user(email), 201
# 410 Gone
# Ресурс был удалён окончательно и больше не вернётся
@app.route('/api/deprecated-endpoint')
def deprecated():
return jsonify({'error': 'This endpoint is gone'}), 410
# 413 Payload Too Large
# Тело запроса слишком большое
# 429 Too Many Requests
# Rate limiting - клиент слишком часто делает запросы
@app.before_request
def check_rate_limit():
if is_rate_limited(request.remote_addr):
return jsonify({'error': 'Rate limited'}), 429
5xx — Ошибки сервера (Server Errors)
Сервер не может обработать корректный запрос из-за своей ошибки.
import logging
from flask import Flask, jsonify
app = Flask(__name__)
logger = logging.getLogger(__name__)
# 500 Internal Server Error
# Неопределённая ошибка на сервере
@app.route('/api/data')
def get_data():
try:
return jsonify(fetch_data())
except Exception as e:
logger.error(f'Unexpected error: {e}', exc_info=True)
return jsonify({'error': 'Internal server error'}), 500
# 501 Not Implemented
# Сервер не поддерживает функциональность
@app.route('/api/advanced-feature')
def advanced():
return jsonify({'error': 'Not implemented'}), 501
# 502 Bad Gateway
# Шлюз получил неверный ответ от upstream сервера
# Обычно генерируется Nginx/Apache, не приложением
# Но можно проверить в логах и обработать
# 503 Service Unavailable
# Сервис временно недоступен (техническое обслуживание, перегруз)
@app.route('/api/data')
def get_data():
if not database.is_connected():
return jsonify({'error': 'Service temporarily unavailable'}), 503
return jsonify(fetch_data())
# 504 Gateway Timeout
# Upstream сервер не ответил вовремя
# Обычно генерируется прокси-сервером
# 505 HTTP Version Not Supported
# Сервер не поддерживает версию HTTP в запросе
Обработка ошибок в приложении
from flask import Flask, jsonify
from werkzeug.exceptions import HTTPException
app = Flask(__name__)
@app.errorhandler(404)
def not_found(error):
return jsonify({'error': 'Resource not found', 'status': 404}), 404
@app.errorhandler(500)
def server_error(error):
logger.error(f'Server error: {error}')
return jsonify({'error': 'Internal server error', 'status': 500}), 500
# Глобальный обработчик для всех HTTPException
@app.errorhandler(HTTPException)
def handle_http_error(error):
return jsonify({
'error': error.description,
'status': error.code
}), error.code
Таблица для быстрого справки
| Код | Название | Значение |
|---|---|---|
| 200 | OK | Всё хорошо |
| 201 | Created | Создано |
| 204 | No Content | Успех, нет тела |
| 301 | Moved Permanently | Постоянный редирект |
| 302 | Found | Временный редирект |
| 304 | Not Modified | Кеш актуален |
| 400 | Bad Request | Ошибка в запросе |
| 401 | Unauthorized | Нужна аутентификация |
| 403 | Forbidden | Нет прав |
| 404 | Not Found | Не найдено |
| 409 | Conflict | Конфликт (дубликат) |
| 429 | Too Many Requests | Rate limit |
| 500 | Internal Server Error | Ошибка сервера |
| 503 | Service Unavailable | Недоступно |
Понимание HTTP статус-кодов критично для разработки надёжных API, так как клиент использует эти коды для определения результата и необходимых действий.