Разбираем Stateful и Stateless API на Python: как работают, когда применять, плюсы и минусы. Практические примеры и ответы на вопросы с собеседований.
Вы когда-нибудь задумывались, почему одни API помнят вас, а другие — нет? Понимание разницы между Stateful и Stateless API — один из самых частых вопросов на собеседованиях backend и frontend разработчиков. В этой статье мы разберем, как они работают, когда их использовать, и рассмотрим примеры на Python. Вы узнаете не только определения, но и практические trade-offs, которые помогут вам принимать верные архитектурные решения.
Состояние — это информация о предыдущих взаимодействиях пользователя. Например:
Ключевой вопрос: кто хранит эту информацию — сервер или клиент?
Stateful API хранит состояние клиента между запросами. Сервер создает сессию и хранит ее у себя. Клиент отправляет только идентификатор сессии (обычно в cookie).
Пример на Python (Flask):
from flask import Flask, session, jsonify, request
app = Flask(__name__)
app.secret_key = 'supersecretkey'
@app.route('/login', methods=['POST'])
def login():
# Проверяем логин и пароль (упрощенно)
username = request.json.get('username')
# Создаем сессию — сервер хранит состояние
session['user'] = username
session['role'] = 'admin'
return jsonify({'message': 'Logged in'})
@app.route('/profile')
def profile():
# Сервер сам знает, кто мы — сессия уже есть
if 'user' in session:
return jsonify({'user': session['user'], 'role': session['role']})
return jsonify({'error': 'Not logged in'}), 401
if __name__ == '__main__':
app.run()Плюсы:
Минусы:
Stateless API не хранит состояние. Каждый запрос содержит всю необходимую информацию для обработки. Обычно это JWT (JSON Web Token), который клиент отправляет в заголовке Authorization.
Пример на Python (Flask + PyJWT):
import jwt
from flask import Flask, request, jsonify
from datetime import datetime, timedelta
app = Flask(__name__)
SECRET = 'supersecretkey'
@app.route('/login', methods=['POST'])
def login():
username = request.json.get('username')
# Создаем JWT — вся информация в токене
payload = {
'user': username,
'role': 'admin',
'exp': datetime.utcnow() + timedelta(hours=1)
}
token = jwt.encode(payload, SECRET, algorithm='HS256')
return jsonify({'token': token})
@app.route('/profile')
def profile():
auth_header = request.headers.get('Authorization')
if not auth_header:
return jsonify({'error': 'No token'}), 401
token = auth_header.split(' ')[1] # Bearer
try:
payload = jwt.decode(token, SECRET, algorithms=['HS256'])
return jsonify({'user': payload['user'], 'role': payload['role']})
except jwt.ExpiredSignatureError:
return jsonify({'error': 'Token expired'}), 401
except jwt.InvalidTokenError:
return jsonify({'error': 'Invalid token'}), 401
if __name__ == '__main__':
app.run() Плюсы:
Минусы:
| Характеристика | Stateful | Stateless |
|---|---|---|
| Сервер хранит сессию | Да | Нет |
| Клиент отправляет | Session ID | JWT / API Token |
| Горизонтальное масштабирование | Сложнее | Легко |
| Logout | Простой | Требует стратегии инвалидации |
| Типичные сценарии | Традиционные веб-приложения | REST API, мобильные приложения, микросервисы |
Stateful: банковские сайты, классические серверные приложения (Django с сессиями).
Stateless: мобильные приложения, SPA на React, публичные REST API, микросервисы.
Современные приложения часто сочетают оба подхода. Например:
Такой гибрид дает: быструю аутентификацию, хорошую масштабируемость и повышенную безопасность.
Прямо сейчас определите, какой подход используется в вашем проекте. Если вы используете сессии — подумайте, не пора ли перейти на JWT для улучшения масштабируемости. Если используете JWT — убедитесь, что у вас настроена ротация токенов и короткое время жизни access токена. Понимание этих концепций выделит вас на собеседовании и поможет строить надежные системы.
Хочешь закрепить знания на практике?
Решай задачи на Algolit — интерактивная платформа для обучения
Начать бесплатно →