Drupal как backend: GraphQL, JSON:API, RESTful и дорогостоящая ошибка, скрытая в выборе API
Однажды CTO спросил меня посреди встречи по планированию decoupled Drupal: «Так какой API нам использовать?»
На секунду в комнате стало тихо. Frontend хотел GraphQL. Backend хотел JSON:API. Один интеграционный подрядчик уже предположил REST. Product owner просто хотел, чтобы мобильное приложение перестало ждать релизов сайта.
Этот маленький вопрос обычно звучит как технический. Но это не так. Это вопрос управления, вопрос бюджета, а иногда и вопрос найма, переодетый в худи разработчика.
Drupal может быть очень мощным backend для decoupled-продуктов. В нём уже есть структурированный контент, роли, разрешения, workflows, ревизии, переводы, работа с медиа, таксономия и зрелая экосистема модулей. Неловкая часть — решить, как именно этот контент будет выходить из Drupal. В ядре Drupal есть нативная поддержка JSON:API, GraphQL доступен через contributed-модуль, а модуль Drupal RESTful Web Services остаётся вариантом для кастомных endpoints в стиле ресурсов. Собственная документация Drupal по decoupled-подходу формулирует разделение прямо: JSON:API находится в ядре, GraphQL является contributed-модулем, а Drupal может отдавать контент внешнему frontend через API.
И всё же команды продолжают выбирать плохо.
Они выбирают GraphQL, потому что он звучит современно. Они выбирают REST, потому что все им пользовались. Они выбирают JSON:API, потому что он уже есть. Ни одно из этого не является стратегией.
Вот более резкая версия: для большинства контентных платформ на базе Drupal JSON:API должен быть стартовой точкой по умолчанию. GraphQL нужно заслужить. REST стоит оставлять для случаев, когда два других варианта слишком широки или слишком навязчивы в своих предположениях.
Кого-то это раздражит. Отлично.
Начните со скучного победителя: JSON:API
JSON:API скучен в самом лучшем смысле.
Модуль JSON:API в ядре Drupal реализует спецификацию JSON:API для сущностей Drupal. Он предоставляет opinionated-способ без дополнительной настройки для раскрытия CRUD-операций с контентом сайта и интегрирован с Entity API, Field API, кешированием, аутентификацией и авторизацией Drupal.
В этом предложении есть часть, которая должна интересовать руководителей: модуль ядра.
Ядро имеет значение. Ядро обычно означает меньше сюрпризов от поставщиков, более простое планирование поддержки, более понятную позицию по безопасности и меньший риск в стиле «нам нужен тот единственный подрядчик, который понимает кастомный API-слой». Документация Drupal по JSON:API говорит, что модуль предоставляет API вокруг типов сущностей и bundles, поддерживает фильтрацию, includes, пагинацию, сортировку, ревизии, переводы, GET, POST, PATCH, DELETE, загрузку файлов и кастомизацию ресурсов через события.
Практический пример: представьте медиа-компанию со статьями, авторами, темами, тизерами для landing pages и изображениями. Frontend-команде нужны страницы статей в Next.js. Мобильному приложению нужен тот же текст статьи, hero-изображение, имя автора и связанные темы. JSON:API может отдавать эти сущности Drupal, не заставляя backend-команду изобретать язык API с нуля. Связанные ресурсы можно встраивать через includes, а коллекции можно фильтровать или пагинировать.
Красивый ли payload? Иногда. Иногда он выглядит так, будто комитет проектировал его после долгого обеда.
Но в этом тоже смысл. JSON:API — это спецификация, а не личный вкус разработчика. Официальный сайт JSON:API описывает его как спецификацию для построения API в JSON, с общими соглашениями, которые уменьшают споры о форме ответа и помогают командам использовать универсальные инструменты. Его media type — application/vnd.api+json, а версия 1.1 была финализирована 30 сентября 2022 года.
Здесь есть скрытая управленческая выгода. Стандартизованный формат ответа означает, что onboarding меньше зависит от племенного знания. Новый frontend-разработчик всё ещё может ругаться на вложенную структуру data, attributes и relationships. Хорошо. По крайней мере, он ругается на что-то задокументированное.
Подвох, о котором никто не хочет говорить
JSON:API довольно напрямую раскрывает контентную модель Drupal. Это может быть преимуществом, особенно когда Drupal является редакционным source of truth. Но это также может слишком сильно протекать внутренней структурой Drupal во frontend.
Если ваша контентная модель чистая, JSON:API ощущается эффективным. Если ваша контентная модель — музей старых компромиссов, JSON:API делает этот беспорядок видимым.
Я видел типы контента “Article” с полями вроде field_new_body_2021, field_mobile_summary, field_legacy_related и field_do_not_use. JSON:API не превращает это магически в изящный продуктовый API. Он показывает модель, которая у вас действительно есть. Возможно, немного жестоко. Но полезно.
Документация Drupal также чётко обозначает границу: JSON:API занимается entity-oriented CRUD, но бизнес-правила вроде входа в систему, сброса пароля и создания аккаунта находятся вне зоны ответственности JSON:API. Если вашему приложению нужны доменные действия вроде «одобрить поставщика», «рассчитать предложение на продление» или «отправить заявку», не пытайтесь втиснуть их в endpoints контентных сущностей только потому, что модуль удобен.
Этот путь быстро становится некрасивым.
GraphQL кажется элегантным, потому что переносит боль
GraphQL соблазнителен. Frontend запрашивает ровно те поля, которые ему нужны. Ответ имеет ту же форму, что и запрос. У него есть типизированная схема. Он кажется созданным для component-based frontends, потому что, откровенно говоря, так и было. Официальный сайт GraphQL описывает GraphQL как open-source язык запросов и server-side runtime для API со строго типизированной схемой, и показывает, как клиент запрашивает выбранные поля вместо того, чтобы получать фиксированный ответ сервера.
Для frontend-команд это реальное улучшение.
Возьмём homepage, составленную из компонентов: hero, избранные статьи, события, слоты спонсоров, навигация, региональные предупреждения. С REST frontend может вызывать несколько endpoints. С JSON:API он может запросить коллекцию и включить связанные ресурсы, но структура всё равно следует отношениям сущностей. С GraphQL запрос может быть ближе к экрану. Это важно, когда команды быстро выпускают продуктовые поверхности.
Модуль GraphQL для Drupal позволяет разработчикам создавать и раскрывать GraphQL-схему для Drupal 10 и 11. Он построен на webonyx/graphql-php, поддерживает официальную спецификацию GraphQL, включает GraphiQL по адресу /graphql/explorer и даёт разработчикам data producer plugins плюс кастомный код для работы со схемой.
Внимательно прочитайте формулировку: «создавать и раскрывать».
Текущий модуль GraphQL для Drupal — это не магическое зеркало, которое просто отражает каждое поле Drupal в аккуратный API. Drupal.org говорит, что более старая версия 3.x автоматически генерировала схему из сущностей Drupal и раскрывала детали Drupal через API, тогда как 4.x оставляет дизайн схемы разработчику, чтобы внутренности Drupal можно было скрыть. На той же странице сказано, что 4.x требует от разработчика настроить и сопоставить схему.
Это не сноска. Это счёт.
GraphQL может дать вам чистый контракт между продуктом и хранилищем контента. Но кто-то должен спроектировать этот контракт. Кто-то должен поддерживать его, когда редакторы добавляют поля, когда меняется дизайн-система, когда появляется персонализация, когда юридический отдел просит региональную логику согласий, когда мобильной команде нужна offline-синхронизация.
На самом деле, это слишком вежливо. Кто-то должен владеть этим. Ownership — это отсутствующая строка бюджета во многих предложениях по GraphQL.
Когда GraphQL стоит своих затрат
GraphQL имеет смысл, когда API является продуктом само по себе.
Большой университет с десятками микросайтов, мобильным приложением для студентов, digital signage, профилями преподавателей, каталогами курсов и дизайн-системой может выиграть от GraphQL-слоя. Потребители разнообразны. Граф контента глубокий. Frontend-командам нужен избирательный доступ. Организация может хотеть API-контракт, который скрывает странности Drupal bundles.
GraphQL также подходит, когда Drupal — лишь один источник среди нескольких. Возможно, контент приходит из Drupal, цены — из ERP, доступность — из booking engine, а права пользователей — из CRM. GraphQL может представить клиентам целостную схему, пока resolvers получают данные из разных систем. Модель GraphQL построена вокруг строго типизированной схемы и формы ответа, задаваемой клиентом, и именно поэтому она хорошо работает в таком composition layer.
Но для обычного маркетингового сайта с headless frontend? Я был бы скептичен. Даже слегка раздражён.
Если реальная потребность — «React должен читать статьи из Drupal», GraphQL может оказаться костюмированной вечеринкой. Вы потратите архитектурные деньги, чтобы избежать изучения includes и filters в JSON:API. Хуже того, вы можете создать bespoke API layer, который понимают только два разработчика.
Страница проекта GraphQL для Drupal сообщает, что стабильные релизы покрываются политикой security advisories Drupal, и перечисляет недавние релизы для Drupal 10 и 11, включая 8.x-4.14, выпущенный 29 апреля 2026 года, и beta 5.0.0 для Drupal 10.4 и 11. Это здоровый признак. Но он не устраняет работу по дизайну.
Contributed-модуль может быть зрелым и всё равно быть неправильным вариантом по умолчанию.
RESTful Web Services: старый, полезный и обычно переиспользуемый
REST стал одним из тех слов, которые означают всё, что нужно говорящему. Иногда это означает чистый resource-oriented HTTP. Иногда — «мы возвращаем JSON из controller». Иногда — «поставщик дал нам endpoint и PDF».
Диссертация Роя Филдинга представила REST как архитектурный стиль для распределённых гипермедиа-систем, с ограничениями вроде разделения client-server, stateless-коммуникации, cache, uniform interface, layered systems и optional code-on-demand. Эта исходная идея строже, чем многое из того, что называют REST в проектных планах.
Модуль RESTful Web Services в Drupal полезен, потому что может раскрывать ресурсы с конкретными методами, форматами сериализации и аутентификацией. Учебные материалы Drupal описывают REST-ресурсы для сущностей, поддержку методов вроде GET, POST, PATCH и DELETE, сериализацию JSON или XML и аутентификацию через Basic Auth, cookies или другие модули, такие как OAuth. Также отмечается, что небезопасные методы требуют request header X-CSRF-Token.
Это делает REST хорошим вариантом для узких интеграционных задач.
Платёжный провайдер отправляет в Drupal статус транзакции. Складская система забирает список обновлённых руководств по продуктам. Partner portal нуждается в одном тщательно сформированном endpoint для одобренных assets. Legacy-мобильное приложение уже ожидает /api/v1/articles/{id} и не может быть переписано в этом квартале.
REST даёт вам контроль. Он также даёт синдром чистого листа.
В отличие от JSON:API, где соглашения уже выбраны, кастомный REST endpoint требует решений: форма URL, формат ответа, формат ошибки, стиль пагинации, синтаксис фильтрации, versioning, аутентификация, cache headers, документация, политика deprecation. OpenAPI может помочь документировать эту поверхность, а OpenAPI Specification — это стандартный, независимый от языка способ описывать HTTP API так, чтобы люди и компьютеры могли понимать их без чтения исходного кода.
Но всё равно вам придётся сделать выбор.
И этот выбор остаётся. Небрежный endpoint, спроектированный на второй неделе, может годами преследовать продукт, потому что какая-то версия приложения в продакшене всё ещё от него зависит.
Решение — это не «какой API лучший?»
Такая постановка вопроса ленива. Извините, но это так.
Лучший вопрос: какой тип связанности ваша организация может себе позволить?
JSON:API связывает потребителей с моделью сущностей Drupal. Это часто приемлемо, когда Drupal является основной контентной системой, а frontend — заменяющим presentation layer. Награда — скорость и меньше изобретений на backend.
GraphQL связывает потребителей со схемой, спроектированной вашей командой. Если сделано хорошо, эта схема скрывает Drupal и выражает продуктовый домен. Если плохо — она становится второй CMS-моделью, поддерживаемой в коде.
REST связывает потребителей с кастомными endpoints. Это отлично для конкретных интеграций и опасно для широкого распространения контента, потому что каждый endpoint становится миниатюрным продуктом со своим хвостом поддержки.
Вот версия, которую я бы вынес на обсуждение исполнительной steering group.
| Ситуация | Моя рекомендация | Почему |
|---|---|---|
| Headless-сайт или приложение, читающее контент из Drupal | Начните с JSON:API | Он находится в ядре Drupal, быстро раскрывает сущности и использует разрешения и кеширование Drupal. |
| Многим frontend нужны разные формы одного и того же контента | Рассмотрите GraphQL | Клиенты могут запрашивать выбранные поля через типизированную схему, но Drupal GraphQL требует проектирования и маппинга схемы. |
| Партнёрская интеграция или разовое подключение системы | Используйте REST | Кастомные REST-ресурсы можно сформировать под интеграцию и контролировать по методу, формату и аутентификации. |
| Модель Drupal беспорядочная, но её нельзя скоро привести в порядок | GraphQL или кастомный REST могут защитить потребителей | Спроектированный API может скрыть внутренние поля, хотя добавляет стоимость ownership и поддержки. |
| Маленькая команда, жёсткий срок, в основном доставка контента | JSON:API | Меньше кастомного API-кода обычно означает меньше сюрпризов. Drupal JSON:API не требует настройки и понимает сущности. |
Таблицы немного стерильны, но эта экономит встречи.
На что должны смотреть project managers
Выбор API меняет план проекта сильнее, чем люди признают.
С JSON:API критический путь — это моделирование контента. Если контентная модель продумана, работа над API может идти быстро. Если контентная модель хаотична, frontend-разработка замедляется, потому что каждый запрос раскрывает очередной редакционный компромисс. Направьте внимание senior-специалистов на naming полей, переиспользуемые paragraph patterns, связи медиа, таксономию и permissions до того, как frontend-команда начнёт связывать страницы.
С GraphQL критический путь — это ownership схемы. Кто проектирует схему? Кто ревьюит breaking changes? Кто пишет resolvers? Кто занимается проблемами производительности вроде вложенных запросов, которые вызывают слишком много backend-загрузок? Модуль Drupal GraphQL даёт инструменты и extension points, включая data producer plugins и GraphiQL, но не устраняет необходимость в backend engineering discipline.
С REST критический путь — это дисциплина контракта. Каждый endpoint нуждается в документации, тестах, правилах аутентификации, семантике ошибок и истории versioning. REST выглядит дешёвым, когда построен первый endpoint. Пятый endpoint говорит правду.
Ещё одно. Аутентификацию часто недооценивают. Drupal JSON:API связан с системами аутентификации и авторизации Drupal, а REST может использовать authentication providers вроде Basic Auth и cookies, при этом OAuth часто добавляется через contributed-модули. Документация Lupus Decoupled Drupal указывает на Simple OAuth как способ аутентифицировать API-запросы по токену в decoupled-настройках.
Не оставляйте это на спринт перед запуском. Этот спринт уже проклят.
Производительность: аргумент, который все упрощают
Поклонники GraphQL говорят, что он избегает over-fetching. Правда. Поклонники JSON:API говорят, что includes уменьшают количество round trips. Тоже правда. Поклонники REST говорят, что HTTP-кеширование straightforward. И снова правда.
Теперь неприятная часть: все три варианта могут быть быстрыми, и все три могут быть медленными.
GraphQL может уменьшить размер payload, но сложные вложенные запросы могут наказать backend, если resolvers написаны небрежно. JSON:API может использовать response caching Drupal и includes, но payloads могут быть многословными. REST может аккуратно ложиться на HTTP-кеширование, но кастомные endpoints часто забывают о cacheability до начала performance testing. Ограничения REST у Филдинга включают cache, потому что cache может уменьшить сетевой трафик и latency, но устаревшие данные и cache invalidation остаются реальными trade-offs. Документация Drupal JSON:API явно связывает модуль с response caching Drupal, а модуль GraphQL на Drupal.org отнесён к категориям Decoupled, Developer tools и Performance.
Так что нет, GraphQL не является автоматически «вариантом для производительности».
Первый выигрыш в производительности обычно даёт лучшая контентная модель. Второй — стратегия кеширования. Третий — избегание глупого поведения клиента, например вызова одного и того же endpoint двенадцать раз, потому что никто не написал data access layer.
Гламурно? Нет. Эффективно? Да.
Прямолинейный framework выбора
Если бы я консультировал founder или CTO, я бы начал с такой последовательности.
Во-первых, используйте обычные rendered pages Drupal, если у вас нет причины decouple. Decoupling добавляет сложность в hosting, preview, routing, cache, deployment, authentication и debugging. Собственная decoupled-документация Drupal отделяет стандартный Drupal от decoupled Drupal, отмечая, что layout переезжает во frontend, а backend раскрывает контент через API. Этот сдвиг не бесплатен.
Во-вторых, если вы decouple в основном ради современного frontend, начните с JSON:API. Постройте одну настоящую страницу, не демо. Включите media, menus или navigation, related content, preview needs, authentication при необходимости и cache behavior. Вы узнаете больше из одной некрасивой страницы, чем из шести архитектурных диаграмм.
В-третьих, переходите на GraphQL только тогда, когда consumer experience оправдывает работу со схемой. Хорошие причины включают нескольких frontend-потребителей, необходимость скрыть внутренности Drupal, сложные content graphs или агрегацию между системами. Плохие причины включают «нашему frontend-разработчику нравится Apollo» и «в investor deck написано GraphQL».
В-четвёртых, используйте REST для интеграций, которым нужны жёсткие границы. Кастомный endpoint для partner export может быть чистым. Целая контентная платформа из hand-rolled endpoints может превратиться в ящик с неподписанными ключами.
И приведите модель Drupal в порядок. Пожалуйста. Ни один API-слой не может полностью спасти контентную модель, которой никто не владеет.
Политика «future-proof»
Руководителям нравится фраза «future-proof». Я понимаю почему. Никто не хочет одобрить перестройку backend и услышать через восемнадцать месяцев, что выбранный API загнал компанию в угол.
Но future-proofing обычно меньше связан с выбором самого модного API и больше — с тем, где разрешено происходить изменениям.
JSON:API говорит: «Модель Drupal — это контракт». Это честно и быстро.
GraphQL говорит: «Наша продуктовая схема — это контракт». Это мощно и дорого.
REST говорит: «Этот endpoint — это контракт». Это точно и легко размножается в проблему поддержки.
Универсального победителя нет. Есть только соответствие.
Мой подход прост: начинайте с наименее кастомной вещи, которая может поддержать продукт. В Drupal это обычно означает JSON:API. Добавляйте GraphQL, когда можете назвать владельца и бюджет. Добавляйте REST, когда интеграция достаточно специфична, чтобы заслужить собственную дверь.
Худший выбор — тот, который сделан ради моды, потому что мода никогда не приходит на поддержку.
Ищете компанию №1 на рынке по разработке на Drupal? Вы только что её нашли.
Мы — лучшая digital-агенция, специализирующаяся на Drupal и созданная для быстрой поставки безопасных, масштабируемых платформ без компромиссов. От новых проектов и редизайнов до миграций и долгосрочной поддержки — наши эксперты по Drupal обеспечивают результаты enterprise-уровня с вниманием уровня boutique-агентства.
Забронируйте звонок сегодня, и давайте превратим ваш Drupal roadmap в высокопроизводительную реальность.
Ivan Abramenko, Principal Drupal Architect
ivan.abramenko@drupalbook.org
projects@drupalbook.org