Headless в Drupal: типичные ошибки и как их избежать
Drupal может отдавать контент через JSON:API, а отдельный фронтенд — собирать из него сайт. Но вместе с шаблонами не исчезают права доступа, кеширование и маршруты: если не учесть их на стыке систем, пользователи увидят старые данные, пустые страницы или утечки закрытого контента.

В headless-проекте на Drupal контент хранится и редактируется в Drupal, а интерфейс строит отдельное приложение — например, на React или Vue. Подключить фронтенд к JSON:API обычно проще, чем договориться о поведении кеша, доступе к материалам и маршрутах. Разберём типичные ошибки именно этой связки: примеры относятся к Drupal 10 и 11, а конкретные возможности стоит сверять с документацией установленной версии и подключённых модулей.
Считать JSON:API готовым контрактом для фронтенда
В Drupal JSON:API входит в ядро, но это не означает, что API автоматически совпадёт с потребностями интерфейса. Стандартный ресурс для материалов может содержать больше полей, чем нужны карточке, и меньше данных, чем ожидает страница: например, авторизованный редактор рассчитывает увидеть черновик, а анонимный посетитель — только опубликованное.
Проверьте контракт на конкретных сценариях, а не на одном успешном GET-запросе. Для каждого типа страницы зафиксируйте, какие поля обязательны, какие связи нужны и что должно происходить с неопубликованным материалом. Встроенный JSON:API следует рассматривать как API с заданными правилами сериализации и доступа, а не как универсальный конструктор произвольных ответов.
- Составьте перечень сущностей и полей для главной, списка материалов и детальной страницы.
- Проверьте ответы для анонимного пользователя и редактора отдельно.
- Не передавайте секретные поля во фронтенд с расчётом скрыть их в интерфейсе. Если API их отдал, пользователь может увидеть ответ в инструментах браузера.
Путать отсутствие поля с пустым значением
Фронтенд часто ломается не на обычном опубликованном материале, а на старой записи, где поле не заполнено, или на типе контента, где этого поля вообще нет. Нельзя без проверки считать, что связь с изображением, автором или категорией всегда существует и содержит ожидаемую структуру.
Обрабатывайте три состояния отдельно: поле отсутствует, поле присутствует без значения, значение есть. Для связей проверяйте также, доступен ли связанный ресурс текущему пользователю. Если API не возвращает его из-за прав, это не обязательно означает, что запись повреждена.
Учитывайте несколько языков
Мультиязычный контент добавляет ещё один источник расхождений. Фронтенд может запросить нужную языковую версию, но не получить её, если перевод не создан или недоступен. Определите поведение заранее: показывать исходный язык, скрывать материал или выводить страницу без перевода. Не подменяйте отсутствие перевода пустыми строками, если интерфейс должен объяснить пользователю, что произошло.
Открывать API шире, чем нужно
«Фронтенду нужен доступ» — недостаточное описание политики безопасности. Проверьте доступ к типам сущностей, полям и конкретным материалам с ролями, которые будут использовать редакторы и посетители. Отдельно испытайте неопубликованные записи, пользовательские данные и связанные сущности.
Не выдавайте фронтенду административные права ради удобства предпросмотра. Публичная выдача и редакторский предпросмотр — разные сценарии, и их лучше разделять по доступу и маршрутам. Если для предпросмотра нужна авторизация, храните учётные данные на серверной стороне, а не в JavaScript-коде, доступном браузеру. Настройки CORS тоже не заменяют проверку прав: разрешённый источник запроса не означает, что запросу можно доверять.
Headless не убирает модель доступа Drupal. Он переносит её последствия из шаблона в HTTP-ответ — туда, где ошибку проще увидеть и сложнее исправить незаметно.
Забывать о кешировании и обновлении данных
Drupal и фронтенд-приложение могут кешировать один и тот же материал независимо. Если Drupal обновил запись, а CDN или серверный рендеринг продолжает отдавать старый ответ, проблема выглядит как «Drupal не сохранил изменения». На деле нужно найти слой, где задержалась устаревшая копия.
Сначала определите путь ответа: Drupal, промежуточный кеш, серверный рендеринг, CDN, браузер. Затем проверьте заголовки кеширования и реакцию каждого слоя на изменение материала. Drupal использует cache tags и cache contexts для управления зависимостями и вариативностью кеша; внешнему приложению недостаточно знать, что данные когда-то пришли из Drupal. Схему сброса или обновления кеша проектируют отдельно и проверяют на реальном сценарии публикации.
Кеш-тег — метка зависимости, по которой Drupal может инвалидировать кешированные данные при изменении связанного контента. Сам по себе этот механизм не гарантирует, что внешний CDN или фронтенд получит сигнал об обновлении.
Смешивать адреса страниц Drupal и фронтенда
У записи может быть Drupal-путь, адрес JSON:API и публичный URL, который должен открываться в браузере. Это разные адреса. Если генерировать ссылки во фронтенде из внутреннего пути Drupal без согласованного правила, пользователь может попасть на сервер CMS, получить неправильный домен или увидеть маршрут, которого нет в приложении.
Задайте единый способ строить публичные URL. Проверьте материалы с псевдонимами, вложенные разделы, перенаправления и старые ссылки. Публикация контента не должна молча создавать ссылку, которую фронтенд не умеет обработать. Отдельно согласуйте поведение для неизвестного маршрута: ответ 404, редирект или страница-заглушка.
Считать предпросмотр обычной публичной страницей
Редактору нужно видеть черновик до публикации, но посетитель не должен получить его через открытый API. Частая ошибка — проверить предпросмотр только под учётной записью администратора и решить, что сценарий готов. Проверьте весь путь: авторизация, получение данных, сборка страницы и возврат в публичный режим после выхода.
Для каждого способа предпросмотра зафиксируйте, кто получает доступ и как долго он действует. Не помещайте токены в постоянные ссылки и клиентский код. Если архитектура требует отдельной серверной части для авторизации, это не лишняя обвязка, а граница между редакторским доступом и публичным сайтом.
Когда выбирать встроенный JSON:API, а когда отдельный слой
Для прямой выдачи Drupal-сущностей встроенный JSON:API часто подходит без дополнительного уровня. Посредник или отдельный API-слой может быть полезен, если фронтенду нужен единый агрегированный ответ из нескольких систем или стабильный контракт, который не должен повторять структуру Drupal. Цена — ещё один компонент, который нужно разрабатывать, мониторить и обновлять.
| Подход | Что выигрываете | Чем платите |
|---|---|---|
| Drupal JSON:API напрямую | Меньше компонентов; данные и права остаются рядом с CMS | Фронтенд теснее связан со структурой Drupal и его ресурсами |
| Промежуточный серверный слой | Можно собрать данные из нескольких источников и скрыть внутреннюю модель CMS | Появляются отдельная логика доступа, кеширования и наблюдения за ошибками |
| Собственный API в Drupal | Контракт можно подстроить под конкретные сценарии продукта | Нужно поддерживать и тестировать дополнительный код и его совместимость |
Выбирайте по контракту, а не по моде
Если приложение в основном показывает Drupal-сущности, начните с JSON:API и проверьте реальные ответы, права и кеширование. Если один экран собирает данные из CMS, каталога и внешнего сервиса, сравните стоимость прямых запросов с отдельным серверным агрегатором. Если нужен специализированный ответ, сначала выясните, можно ли выразить сценарий штатным API; не добавляйте свой слой только потому, что фронтенду удобнее получить один объект.
Что проверить перед запуском
- Контракт. Зафиксируйте ответы для ключевых страниц и проверьте пустые поля, отсутствующие связи и языковые варианты. Успех — приложение не падает на корректном, но неполном материале.
- Доступ. Повторите запросы как анонимный пользователь, редактор и пользователь без нужных прав. Успех — черновик недоступен посетителю, но предпросмотр работает для разрешённой роли.
- Ссылки. Проверьте публичные URL, псевдонимы, неизвестные пути и перенаправления. Успех — ссылки открывают страницы фронтенда, а неизвестный адрес обрабатывается предсказуемо.
- Кеш. Опубликуйте и обновите материал, затем измерьте время до появления новой версии через все слои. Успех — вы знаете, где хранится устаревший ответ и как он инвалидируется.
- Наблюдаемость. Сопоставьте ошибки фронтенда с HTTP-ответом API и журналами Drupal. Успех — по сбою можно определить, кто вернул ошибку: CMS, прокси или приложение.
Что делать дальше
Возьмите один тип контента и проследите его путь от сохранения в Drupal до отображения в браузере. Проверьте права, адреса, кеш и поведение при пустых полях на этом сценарии, прежде чем переносить схему на весь сайт. Следующий практический шаг — измерить время обновления опубликованного материала от нажатия кнопки в CMS до появления новой версии на публичной странице.
Контент-конвейер: Из одной идеи — текст, изображение, озвучка и ролик. Один заказ вместо четырёх.
Спросить за 60 ₽Источники: JSON:API module — Drupal documentation, Cache API — Drupal documentation
Частые вопросы
Можно ли использовать Drupal JSON:API без отдельного сервера?
Почему фронтенд показывает старую версию опубликованной записи?
Как дать редактору предпросмотр черновика, не открывая его посетителям?
Почему API не возвращает перевод или связанный материал?
Нужно ли всегда писать собственный API для headless Drupal?
Одинаково ли это работает в Drupal 10 и 11?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.