Должен ли REST сервис быть stateful
Что проверяют
Знаете ли вы ограничение stateless из диссертации Филдинга и понимаете ли, о каком состоянии в нём речь. Следом обычно спрашивают, где тогда хранить аутентификацию и корзину и чем плоха сессия в памяти инстанса.
Как отвечать
Коротко: нет, REST-сервис должен быть stateless, но это правило про состояние сессии, а не про данные.
- состояние сессии: контекст диалога с конкретным клиентом. По REST он целиком на клиенте, и каждый запрос несёт всё нужное для обработки: токен, параметры, курсор пагинации;
- состояние ресурсов: заказы, пользователи, корзина как ресурс
/carts/{id}в базе. Хранить их на сервере нормально, в этом смысл сервиса.
Что даёт stateless: запрос может обработать любой инстанс, балансировщику не нужны sticky sessions, масштабирование и перезапуск подов проходят без потери контекста, ответы проще кэшировать.
Как это выглядит в Spring:
- Spring Security:
sessionManagement(s -> s.sessionCreationPolicy(SessionCreationPolicy.STATELESS)),HttpSessionне создаётся; - аутентификация: заголовок
Authorization: Bearer ...с JWT, который проверяетoauth2ResourceServer(o -> o.jwt(Customizer.withDefaults())), либо непрозрачный токен с проверкой на сервере авторизации; - если сессии всё-таки нужны: Spring Session с Redis выносит их из памяти инстанса. Формально это отступление от REST, но инстансы остаются взаимозаменяемыми.
Стоит упомянуть цену JWT: выданный токен трудно отозвать, поэтому делают короткий срок жизни, refresh-токены и при необходимости список отозванных.
Где спотыкаются
Путают stateless с «без базы данных». Сервис, который хранит заказы в PostgreSQL, остаётся stateless, если не держит контекст клиента между запросами.
Кладут данные пользователя в HttpSession в памяти одного инстанса и чинят это sticky sessions. При падении инстанса клиент теряет сессию, а нагрузка распределяется неравномерно.
Утверждают, что REST требует JWT. Ограничение говорит лишь о самодостаточности запроса, формат токена остаётся вашим выбором.