Spring Batch
Spring Batch нужен для пакетной обработки: большие файлы, nightly jobs, миграции, отчёты, регулярная синхронизация.
Модель строится вокруг Job, Step, ItemReader, ItemProcessor и ItemWriter. Важные свойства: restartability, chunk processing, skip/retry и job repository.
Ключевая деталь chunk-обработки — commit-interval: Step читает и обрабатывает элементы по одному, но писатель вызывается раз на пачку (chunk), и каждая пачка — это одна транзакция. Размер chunk-а определяет границу транзакции и компромисс: большой chunk быстрее (меньше коммитов), но при сбое откатывается и переобрабатывается вся пачка, плюс растёт потребление памяти. Job repository хранит метаданные выполнения (какие Step/chunk завершились), поэтому после падения job можно перезапустить с места, а не с нуля. Для устойчивости к «плохим» строкам настраивают skip (пропустить запись с ошибкой до лимита) и retry (повторить транзиентную ошибку).
// chunk(100): на каждые 100 элементов — один writer-вызов в одной транзакции
stepBuilder.<Input, Output>chunk(100, txManager)
.reader(reader).processor(processor).writer(writer)
.faultTolerant().skipLimit(10).skip(ParseException.class);
Spring Integration
Spring Integration реализует enterprise integration patterns: channels, endpoints, transformers, routers, filters, adapters.
Его выбирают, когда нужно связать разные транспортные и доменные системы декларативным pipeline, а не писать ручной glue-code в сервисах.
Spring Data REST и HATEOAS
Spring Data REST может быстро публиковать repository как REST API. Это удобно для admin/internal CRUD, но опасно как публичный API без контроля контракта.
HATEOAS добавляет ссылки в представления ресурсов, чтобы клиент мог обнаруживать доступные действия. На практике важно не перегрузить API ссылками без реальной пользы.
GraphQL
GraphQL позволяет клиенту запросить ровно нужные поля и объединить связанные данные одним запросом.
Главные backend-риски: N+1 на resolvers, сложность authorization на уровне полей и защита от слишком дорогих запросов.
N+1 в GraphQL особенно коварен: клиент запрашивает список из N объектов и по вложенному полю каждого — резолвер этого поля вызывается N раз, по запросу в БД на каждый. Стандартное решение — DataLoader: он откладывает (батчит) обращения внутри одного тика и склеивает их в один запрос по списку ключей (плюс кэш в рамках запроса). В Spring for GraphQL это @BatchMapping или BatchLoaderRegistry. Дорогие запросы ограничивают лимитом глубины/сложности (query depth/complexity limit), иначе клиент может уронить сервер одним глубоко вложенным запросом.
Как отвечать на собеседовании
Различайте инструменты по задаче. Spring Batch — пакетная обработка (Job/Step/ItemReader-Processor-Writer, chunk-processing с коммитом по пачкам, restartability, skip/retry, job repository) для больших файлов и ночных задач. Spring Integration — enterprise integration patterns (channels/endpoints/adapters/routers) для декларативной связки систем вместо ручного glue-code.
По стилям API: Spring Data REST быстро публикует репозитории как REST (удобно для internal CRUD, рискованно как публичный контракт), а GraphQL даёт клиенту выбирать поля одним запросом ценой N+1 на резолверах, field-level авторизации и защиты от дорогих запросов. Выбор — от клиента и нужного контроля над контрактом.