Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI23 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Код состояния (Status Code)
Код состояния — это трёхзначное число, которое сервер возвращает в ответ на HTTP запрос клиента. Он указывает результат обработки запроса: успешно ли он выполнен, произошла ли ошибка, требуется ли дополнительное действие. Коды состояния — неотъемлемая часть HTTP протокола.
Классификация кодов состояния
Коды состояния организованы по первой цифре:
- 1xx (1-199) — информационные
- 2xx (200-299) — успешные запросы
- 3xx (300-399) — перенаправления
- 4xx (400-499) — ошибки клиента
- 5xx (500-599) — ошибки сервера
1xx — Информационные коды
# 100 Continue — сервер готов получить тело запроса
# 101 Switching Protocols — сервер переходит на другой протокол
2xx — Успешные коды
# 200 OK — запрос успешен, результат возвращен
# 201 Created — ресурс успешно создан
# 202 Accepted — запрос принят, но обработка ещё не завершена
# 204 No Content — успешен, но нет содержимого для возврата
from flask import Flask, jsonify
from http import HTTPStatus
app = Flask(__name__)
@app.route('/users', methods=['GET'])
def get_users():
"""Возвращает 200 OK"""
return jsonify([
{'id': 1, 'name': 'Alice'},
{'id': 2, 'name': 'Bob'}
]), HTTPStatus.OK # 200
@app.route('/users', methods=['POST'])
def create_user():
"""Возвращает 201 Created"""
new_user = {'id': 3, 'name': 'Charlie'}
return jsonify(new_user), HTTPStatus.CREATED # 201
@app.route('/users/<id>', methods=['DELETE'])
def delete_user(id):
"""Возвращает 204 No Content"""
return '', HTTPStatus.NO_CONTENT # 204
3xx — Коды перенаправления
# 301 Moved Permanently — ресурс постоянно переместился
# 302 Found — ресурс временно переместился
# 304 Not Modified — кэш всё ещё актуален
from flask import Flask, redirect
from http import HTTPStatus
app = Flask(__name__)
@app.route('/old-endpoint')
def old_endpoint():
"""Перенаправить на новый endpoint"""
return redirect('/api/v1/users', code=HTTPStatus.MOVED_PERMANENTLY) # 301
@app.route('/temporary')
def temporary():
"""Временное перенаправление"""
return redirect('/new-location', code=HTTPStatus.FOUND) # 302
@app.route('/cached-data')
def cached_data():
"""Кэшированные данные не изменились"""
return '', HTTPStatus.NOT_MODIFIED # 304
4xx — Ошибки клиента
# 400 Bad Request — некорректный запрос
# 401 Unauthorized — требуется аутентификация
# 403 Forbidden — доступ запрещён
# 404 Not Found — ресурс не найден
# 409 Conflict — конфликт (например, дубликат)
# 422 Unprocessable Entity — валидация не пройдена
# 429 Too Many Requests — слишком много запросов
from flask import Flask, jsonify, request
from http import HTTPStatus
app = Flask(__name__)
@app.route('/users/<int:user_id>', methods=['GET'])
def get_user(user_id):
"""Возвращает 404 если пользователь не найден"""
user = None # Пользователь не найден
if not user:
return jsonify({'error': 'User not found'}), HTTPStatus.NOT_FOUND # 404
return jsonify(user)
@app.route('/api/data', methods=['POST'])
def create_data():
"""Возвращает 400 при некорректных данных"""
data = request.get_json()
if not data.get('name'):
return jsonify({'error': 'Name is required'}), HTTPStatus.BAD_REQUEST # 400
return jsonify(data), HTTPStatus.CREATED # 201
@app.route('/protected', methods=['GET'])
def protected():
"""Возвращает 401 если не аутентифицирован"""
token = request.headers.get('Authorization')
if not token:
return jsonify({'error': 'Unauthorized'}), HTTPStatus.UNAUTHORIZED # 401
return jsonify({'data': 'secret'})
@app.route('/admin', methods=['GET'])
def admin():
"""Возвращает 403 если нет прав"""
is_admin = False # Пользователь не администратор
if not is_admin:
return jsonify({'error': 'Forbidden'}), HTTPStatus.FORBIDDEN # 403
return jsonify({'admin_data': '...'})
@app.route('/users', methods=['POST'])
def create_user_with_validation():
"""Возвращает 422 при ошибке валидации"""
data = request.get_json()
# Валидация
if not data.get('email'):
return jsonify({'error': 'Email is required'}), HTTPStatus.UNPROCESSABLE_ENTITY # 422
if '@' not in data['email']:
return jsonify({'error': 'Invalid email format'}), HTTPStatus.UNPROCESSABLE_ENTITY # 422
return jsonify(data), HTTPStatus.CREATED # 201
5xx — Ошибки сервера
# 500 Internal Server Error — общая ошибка сервера
# 501 Not Implemented — функционал не реализован
# 502 Bad Gateway — ошибка шлюза
# 503 Service Unavailable — сервис недоступен
# 504 Gateway Timeout — таймаут шлюза
from flask import Flask, jsonify
from http import HTTPStatus
import logging
app = Flask(__name__)
logger = logging.getLogger(__name__)
@app.route('/data', methods=['GET'])
def get_data():
"""Возвращает 500 при необработанном исключении"""
try:
# Некоторая операция
result = 1 / 0 # ZeroDivisionError
return jsonify(result)
except Exception as e:
logger.error(f"Error: {e}")
return jsonify({'error': 'Internal server error'}), HTTPStatus.INTERNAL_SERVER_ERROR # 500
@app.route('/not-implemented', methods=['POST'])
def not_implemented():
"""Возвращает 501 если функция не реализована"""
return jsonify({'error': 'This feature is not yet implemented'}), HTTPStatus.NOT_IMPLEMENTED # 501
@app.route('/maintenance', methods=['GET'])
def maintenance():
"""Возвращает 503 если сервис на обслуживании"""
is_maintenance = True
if is_maintenance:
return jsonify({'error': 'Service is under maintenance'}), HTTPStatus.SERVICE_UNAVAILABLE # 503
return jsonify({'data': '...'})
Работа с кодами состояния в клиенте
import requests
from http import HTTPStatus
url = "https://api.example.com/users"
# Базовая проверка
response = requests.get(url)
if response.status_code == HTTPStatus.OK: # 200
data = response.json()
print(data)
elif response.status_code == HTTPStatus.NOT_FOUND: # 404
print("User not found")
elif response.status_code == HTTPStatus.INTERNAL_SERVER_ERROR: # 500
print("Server error")
# Проверка диапазонов
response = requests.get(url)
if 200 <= response.status_code < 300:
print("Success!")
elif 300 <= response.status_code < 400:
print("Redirect!")
elif 400 <= response.status_code < 500:
print("Client error!")
elif 500 <= response.status_code < 600:
print("Server error!")
# Использование raise_for_status()
response = requests.get(url)
try:
response.raise_for_status() # Выбросит исключение если код >= 400
print("Success!")
except requests.exceptions.HTTPError as e:
print(f"HTTP error: {e}")
Лучшие практики для API
from fastapi import FastAPI, HTTPException, status
from pydantic import BaseModel
app = FastAPI()
class User(BaseModel):
id: int
name: str
email: str
users_db = {
1: User(id=1, name="Alice", email="alice@example.com")
}
@app.get("/users/{user_id}", status_code=status.HTTP_200_OK)
def get_user(user_id: int):
"""Получить пользователя"""
user = users_db.get(user_id)
if not user:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
return user
@app.post("/users", status_code=status.HTTP_201_CREATED)
def create_user(user: User):
"""Создать пользователя"""
if user.id in users_db:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT,
detail="User already exists"
)
users_db[user.id] = user
return user
@app.delete("/users/{user_id}", status_code=status.HTTP_204_NO_CONTENT)
def delete_user(user_id: int):
"""Удалить пользователя"""
if user_id not in users_db:
raise HTTPException(
status_code=status.HTTP_404_NOT_FOUND,
detail="User not found"
)
del users_db[user_id]
return None # 204 No Content
Обработка ошибок с правильными кодами
from flask import Flask, jsonify, request
from http import HTTPStatus
from datetime import datetime
app = Flask(__name__)
class APIException(Exception):
"""Базовое исключение API"""
def __init__(self, message: str, status_code: int = 500, details: dict = None):
self.message = message
self.status_code = status_code
self.details = details or {}
super().__init__()
@app.errorhandler(APIException)
def handle_api_exception(error):
"""Обработчик для APIException"""
response = {
'error': error.message,
'status_code': error.status_code,
'timestamp': datetime.utcnow().isoformat(),
'details': error.details
}
return jsonify(response), error.status_code
@app.route('/calculate', methods=['POST'])
def calculate():
"""Пример обработки ошибок"""
data = request.get_json()
# Валидация
if not data:
raise APIException(
"Request body is required",
status_code=HTTPStatus.BAD_REQUEST,
details={'example': {'a': 5, 'b': 3}}
)
if 'a' not in data or 'b' not in data:
raise APIException(
"Fields 'a' and 'b' are required",
status_code=HTTPStatus.UNPROCESSABLE_ENTITY,
details={'provided_fields': list(data.keys())}
)
try:
result = data['a'] / data['b']
return jsonify({'result': result}), HTTPStatus.OK
except ZeroDivisionError:
raise APIException(
"Division by zero",
status_code=HTTPStatus.BAD_REQUEST,
details={'operation': 'division'}
)
Таблица основных кодов
| Код | Статус | Использование |
|---|---|---|
| 200 | OK | Успешно, возвращены данные |
| 201 | Created | Ресурс успешно создан |
| 204 | No Content | Успешно, нет содержимого |
| 400 | Bad Request | Некорректный запрос |
| 401 | Unauthorized | Требуется аутентификация |
| 403 | Forbidden | Доступ запрещён |
| 404 | Not Found | Ресурс не найден |
| 409 | Conflict | Конфликт (дубликат) |
| 422 | Unprocessable Entity | Ошибка валидации |
| 429 | Too Many Requests | Превышен лимит запросов |
| 500 | Internal Server Error | Ошибка сервера |
| 503 | Service Unavailable | Сервис недоступен |
Итоги
Коды состояния — критический компонент HTTP протокола:
- Информируют клиента о результате запроса
- Позволяют правильно обрабатывать ошибки
- Делают API предсказуемым и стандартизированным
- Требуют правильного выбора для каждой ситуации
Использование правильных кодов состояния — признак хорошего API дизайна и помогает клиентам корректно работать с вашим сервисом.