Некоторое время назад в одной заметной на российском рынке публичной компании, в которой я работал, встал вопрос об использовании headless cms. Среди множества реализаций нужно было выбрать одну. Это рассказ о том, как я формировал критерии выбора, как анализировал cms-ки, и как этот анализ привел меня к мысли, что нужно писать свою. Обзор 14 headless cms под катом.



Что такое headless CMS?


Хоть термин и не нов, почему-то эта тема в русскоязычном интернете освещена крайне мало. Итак, согласно википедии:
A headless content management system, or headless CMS, is a back-end only content management system (CMS) built from the ground up as a content repository that makes content accessible via a RESTful API for display on any device.
Headless система управления контентом, или headless CMS — это серверная система управления контентом (CMS), которая изначально является хранилищем контента и предоставляет доступ к контенту через RESTful API для отображения на любом девайсе.

Другими словами headless cms — это концепция, этакий специальный тип cms-ок, согласно которой cms отвечает только за управление “чистым” контентом. Это позволяет отделить слой данных, который управляется в cms, от слоя отображения, который управляется клиентским приложением. Контент распространяется в универсальном формате, обычно в JSON, это и дает возможность управлять одновременно веб-сайтом, мобильным приложением и любыми устройствами подключенными к интернету.

Подробнее о плюсах и минусах такой концепции можно почитать в этой статье, или этой, или опять же в статье на википедии.

Погружение в контекст


Чтобы определить критерии поиска и понять, какая headless cms лучше других, мне предстояло ответить на вопрос — лучшая в чем? Какие именно задачи она должна решать и как?

Чтобы продемонстрировать мой тогдашний ход мыслей, я придумал типовую задачу и решил ее при помощи одной из headless cms. И хоть в действительности все было чуть по другому, такой формат повествования лаконичней отражает суть и лучше раскрывает тему headless cms.

Итак, представим, что в разработку приходит задача. На сайте нужно реализовать новый раздел, на котором пользователи будут читать обзоры к фильмам.
Условия такие:
  • на данный момент нужно выводить только название фильма, постер, имя режиссера и текст обзора, но в будущем структура усложнится, появится информация о сборах, актерах и и т.д.;
  • добавлять и изменять обзоры должен будет человек без технического бэкграунда — контент-менеджер, и для этого ресурс разработки задействоваться не должен;
  • этот функционал должен быть отключаем, т.е. нужно реализовать feature toggle;
  • перед публикацией контента, контент-менеджер должен иметь возможность посмотреть в тестовом окружении, как будут выглядеть правки.

Это требования, которые поступили от внутреннего заказчика. Со стороны разработки есть свое техническое видение на реализацию, а именно:
  • заказчик не должен иметь возможность прострелить себе колено, т.е. контент-менеджер не должен ничего сломать, даже если захочет. Он должен редактировать только то, что предусмотрели разработчики;
  • должна быть возможность управлять версиями и откатиться в случае чего;
  • неизвестно, какой дополнительный функционал появится в будущем, а это означает, что усложнять или менять раздел должно быть легко;
  • со стороны безопасности: система должна быть на нашем сервере, а не в чужом облаке, т.е. должна быть возможность развернуть on-premises.

Хорошо, с задачей все ясно. Перехожу к решению.

Буду использовать Any JSON CMS, это одна из headless cms. Отмечу, что на данный момент она не удовлетворяет всем требованиям описанным выше. Например, контент-менеджер не сможет посмотреть в тестовом окружении, как будут выглядеть правки. Однако, все достоинства и недостатки будут видны позже. Сейчас же я стремлюсь “пощупать” типовой сценарий работы с любой headless cms.

Первое, что нужно сделать — описать модели. Модель отвечает на вопрос, как должна выглядеть контентная сущность? Какая у нее структура? По сути это протокол взаимодействия между cms и клиентским приложением. В нашем случае — обзор к фильму — объект содержит:
  • 3 обязательных свойства: название фильма, постер фильма, текст обзора;
  • 1 необязательное свойство: объект “режиссер”, который в свою очередь содержит 2 обязательных свойства имя и фамилию.

В виде JSON Schema модель обзора выглядит так:
{
  type: 'object',
  required: ['movieName', 'moviePoster', 'reviewText'],
  additionalProperties: false,
  properties: {
    movieName: {
      type: 'string',
      minLength: 1,
      maxLength: 300,
    },
    moviePoster: {
      type: 'string',
      description: 'URL to file',
    },
    movieProducer: {
      type: 'object',
      required: ['name', 'surname'],
      additionalProperties: false,
      properties: {
        name: { type: 'string', maxLength: 100, minLength: 1 },
        surname: { type: 'string', maxLength: 100, minLength: 1 },
      },
    },
    reviewText: {
      type: 'string',
      minLength: 1,
      maxLength: 3000,
    },
  },
}

Также нужно реализовать feature toggle, модель в виде JSON Schema выглядит так:
{
  type: 'object',
  required: ['isFeatureActive', 'name'],
  additionalProperties: false,
  properties: {
    isFeatureActive: { type: 'boolean' },
    name: { type: 'string', enum: ['movieReviewFeatureToggle'] },
  },
}

Когда есть понимание, как должны выглядеть модели, можно создавать их в Any JSON CMS.



Тут же создаю контентные сущности, т.е. сам контент, на основе моделей. Один фиктивный обзор и feature toggle сущность.



Для интеграции клиентского приложения с cms потребуется API key. Генерирую его в соответствующем разделе cms.


Теперь все готово для реализации функционала в клиентском приложении и интеграции с cms. Клиентское приложение может быть любым — сайт или мобильное приложение, или и то, и другое, написанное на чем угодно. В качестве примера я реализую функционал на сайте SPA на React. По сути мы забираем данные с уже известной, фиксированной структурой из cms и отображаем ее так, как хотим.
import React, { Component } from 'react'
import {
  Accordion,
  AccordionItem,
  AccordionItemTitle,
  AccordionItemBody,
} from 'react-accessible-accordion'

import 'react-accessible-accordion/dist/fancy-example.css'

const apiUrl = 'https://api.anyjsoncms.com'
// ApiKey безопаснее хранить на проксирующем бэкенде
const apiKey = '87414950dfd15648ea560bd89dd0ee02bfc8fcca'

class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      movies: null,
      isFeatureActive: null,
      loading: true,
    }
  }

  componentDidMount() {
    const options = { method: 'GET', headers: { ApiKey: apiKey } }
    Promise.all([
      fetch(`${apiUrl}/entries?apiId=featureToggle`, options).then(resp =>
        resp.json()
      ),
      fetch(`${apiUrl}/entries?apiId=movieReview`, options).then(resp =>
        resp.json()
      ),
    ])
      .then(([featureToggleResp, movieReviewResp]) => {
        const featureToggle = featureToggleResp.find(
          item => item.value.name === 'movieReviewFeatureToggle'
        )
        const isFeatureActive =
          featureToggle &&
          featureToggle.value &&
          featureToggle.value.isFeatureActive
        const movies = movieReviewResp.map(item => item.value)
        this.setState({ movies, isFeatureActive, loading: false })
      })
      .catch(error => {
        console.error(error)
      })
  }

  render() {
    const { movies, isFeatureActive, loading } = this.state
    if (loading) return <div>Loading...</div>
    if (!isFeatureActive)
      return <div style={{ display: 'none' }}>Section is hidden</div>
    return (
      <div>
        <Accordion>
          {movies.map(
            ({ movieName, moviePoster, movieProducer, reviewText }, index) => (
              <AccordionItem key={index}>
                <AccordionItemTitle>
                  <h3>{movieName}</h3>
                </AccordionItemTitle>
                <AccordionItemBody>
                  <img src={`${apiUrl}${moviePoster}`} alt="" />
                  {!movieProducer ? null : (
                    <div>{`${movieProducer.name} ${
                      movieProducer.surname
                    }`}</div>
                  )}
                  <div>{reviewText}</div>
                </AccordionItemBody>
              </AccordionItem>
            )
          )}
        </Accordion>
      </div>
    )
  }
}

export default App

Все. Теперь контент-менеджер может спокойно управлять обзорами, а еще появилась возможность включать и отключать функционал при помощи feature toggle.

Выводить обзоры к фильмам — это простой пример, я намеренно его привел, чтобы не утонуть в деталях, а лишь продемонстрировать принцип. В действительности же фичи могут быть на порядок сложнее. Это могут быть элементы интерфейса, каталоги товаров, сложные виджеты, лендинги, генераторы форм, посты и пр. Также, в этом примере cms только распространяет информацию, однако большинство headless cms предоставляют CRUD API, что дает возможность, например, обрабатывать формы, да и вообще манипулировать сущностями, как угодно. В общем, задумка headless cms как раз в том, чтобы предоставить свободу и удобство в реализации сколь угодно сложного протокола, чтобы передать управление в cms чего угодно и так, как требуется.

Критерии выбора и анализ headless cms


После того, как у меня появилось понимание, какие задачи будут решаться при помощи headless cms и как именно, я выделил критерии и начал изучать системы. Сейчас согласно сайту headlesscms.org существует 54 cms. Проанализировать их все — довольно трудоемкий процесс, поэтому я выделил 14 наиболее популярных, заметных и обсуждаемых систем: Any JSON CMS, Contentful, Strapi, GraphCMS, Squidex, Butter CMS, Cloud CMS, Сockpit, Cosmic JS, Directus, Kentico Cloud, Netlify CMS, Prismic, Ghost.

Результаты удобнее изучать в виде таблицы. Но продублирую и здесь.

Any JSON CMS


Сайт anyjsoncms.com
Описание Headless CMS that could help manage and deliver any JSON to any app
Целевая аудитория Digital teams
Цена в месяц Альфа версия, цены нет
Возможность комерческой поддержки нет
Подписчиков в twitter 0 тыс.
Github stars (если open source) не open source
Open source решение нет
On-premises software нет
Cloud service да
GraphQL API нет
REST API да
Контентная сущность создается на основе модели да
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI да
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) нет
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) да
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) да
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей нет
CRUD API для моделей нет
Поддержка API access tokens да
Разграничение прав для доступа к API по API access token нет
Система публикации: Draft/Publish нет
Возможность отсроченной публикации нет
Фиксация версий моделей нет
Фиксация версий контентных сущностей нет
Git подобная система версионирования нет
Управление проектами да
Управление изображениями да
Управление файлами да
Webhooks нет
Управление пользователями нет
Управление доступами пользователей нет
Дополнительная информация Доступна только альфа версия

Contentful


Сайт contentful.com
Описание Update once and publish everywhere, so teams build digital products faster.
Предназначение Content management in multi-channel world
Целевая аудитория Digital teams, enterprises
Цена в месяц cloud — free, 39$, 879$, hidden price for enterprise
Возможность комерческой поддержки да
Подписчиков в twitter 33,6 тыс.
Github stars (если open source) не open source
Open source решение нет
On-premises software нет
Cloud service да
GraphQL API да
REST API да
Контентная сущность создается на основе модели да
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI да
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) да
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) нет
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) нет
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей да
CRUD API для моделей да
Поддержка API access tokens да
Разграничение прав для доступа к API по API access token да
Система публикации: Draft/Publish да
Возможность отсроченной публикации нет
Фиксация версий моделей да
Фиксация версий контентных сущностей да
Git подобная система версионирования нет
Управление проектами да
Управление изображениями да
Управление файлами да
Webhooks да
Управление пользователями да
Управление доступами пользователей да

Strapi


Сайт strapi.io
Описание Manage your content. Distribute it anywhere.
Предназначение Build powerful content API with no effort
Целевая аудитория Profesional developers
Цена в месяц on-premiss — free
Возможность комерческой поддержки да
Подписчиков в twitter 2,3 тыс.
Github stars (если open source) 11,1 тыс
Open source решение да
On-premises software да
Cloud service нет
GraphQL API да
REST API да
Контентная сущность создается на основе модели да
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI да
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) нет
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) нет
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) нет
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей да
CRUD API для моделей нет
Поддержка API access tokens нет
Разграничение прав для доступа к API по API access token да
Система публикации: Draft/Publish нет
Возможность отсроченной публикации нет
Фиксация версий моделей нет
Фиксация версий контентных сущностей нет
Git подобная система версионирования нет
Управление проектами нет, но можно развернуть отдельный экземпляр cms
Управление изображениями да
Управление файлами да
Webhooks нет, но можно реализовать через lifecycle callbacks
Управление пользователями да
Управление доступами пользователей да
Дополнительная информация Изучал альфа версию, были баги при сохранении модели

GraphCMS


Сайт graphcms.com
Описание Bring content to any platform
Предназначение Content infrastructure for your digital product
Целевая аудитория Profesional developers, agencies, enterprises
Цена в месяц cloud — free, 49$, 149$, 499$, hidden price for enterprise
Возможность комерческой поддержки да
Подписчиков в twitter 2,4 тыс
Github stars (если open source) не open source
Open source решение нет
On-premises software нет
Cloud service да
GraphQL API да
REST API нет
Контентная сущность создается на основе модели да
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI да
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) нет
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) нет
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) да, либо не дает менять модель, либо изменение ведет к потере данных после подтверждения
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей да
CRUD API для моделей нет
Поддержка API access tokens да
Разграничение прав для доступа к API по API access token да
Система публикации: Draft/Publish да
Возможность отсроченной публикации нет
Фиксация версий моделей нет
Фиксация версий контентных сущностей нет
Git подобная система версионирования нет
Управление проектами да
Управление изображениями да
Управление файлами да
Webhooks да
Управление пользователями да
Управление доступами пользователей да

Squidex


Сайт squidex.io
Описание Squidex enables you to manage content in a central place and to use your tech stack for apps, websites and services.
Предназначение Our first priority is to deliver a state of the art, stable, fast and free content management hub to make the life for developers a little bit easier.
Целевая аудитория Profesional developers
Цена в месяц cloud — free, 19$, 49$, 99$; on-premises — free
Возможность комерческой поддержки не анонсирована
Подписчиков в twitter 0 тыс
Github stars (если open source) 0,5 тыс
Open source решение да
On-premises software да
Cloud service да
GraphQL API да
REST API да
Контентная сущность создается на основе модели да
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI да
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) нет
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) нет
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели можно указать single content или multiple content, конкретное кол-во указать нельзя
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) нет
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей да
CRUD API для моделей нет
Поддержка API access tokens да
Разграничение прав для доступа к API по API access token да
Система публикации: Draft/Publish да
Возможность отсроченной публикации да
Фиксация версий моделей нет
Фиксация версий контентных сущностей да
Git подобная система версионирования нет
Управление проектами да
Управление изображениями да
Управление файлами да
Webhooks да
Управление пользователями да
Управление доступами пользователей да

Butter cms


Сайт buttercms.com
Описание Add a blog or CMS to your site in minutes. Drop-in our Headless CMS and get back to more interesting problems.
Предназначение Drop our API-based CMS into any tech stack in minutes.
Целевая аудитория Startups, agencies, enterprises
Цена в месяц cloud — 24$, 83$, 166$, hidden price for enterprise
Возможность комерческой поддержки да
Подписчиков в twitter 0,4 тыс
Github stars (если open source) не open source
Open source решение нет
On-premises software нет
Cloud service да
GraphQL API нет
REST API да
Контентная сущность создается на основе модели да
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI да
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) нет
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) нет
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) нет
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей нет
CRUD API для моделей нет
Поддержка API access tokens да
Разграничение прав для доступа к API по API access token нет (и не требуется, т.к. есть только read)
Система публикации: Draft/Publish да
Возможность отсроченной публикации нет
Фиксация версий моделей нет
Фиксация версий контентных сущностей да
Git подобная система версионирования нет
Управление проектами да
Управление изображениями да
Управление файлами да
Webhooks да
Управление пользователями да
Управление доступами пользователей да

Cloud CMS


Сайт cloudcms.com
Описание Easy for Content Editors + Powerful for Developers
Предназначение CMS for business critical applications
Целевая аудитория Enterprise
Цена в месяц 200$, 800$, 1200$
Возможность комерческой поддержки да
Подписчиков в twitter 0,3 тыс
Github stars (если open source) не open source
Open source решение нет
On-premises software да
Cloud service да
GraphQL API да
REST API да
Контентная сущность создается на основе модели да
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI да
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) да
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) да
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) нет
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей да
CRUD API для моделей да
Поддержка API access tokens да
Разграничение прав для доступа к API по API access token нет
Система публикации: Draft/Publish да, можно включить в настройках
Возможность отсроченной публикации нет
Фиксация версий моделей да
Фиксация версий контентных сущностей да
Git подобная система версионирования да
Управление проектами да
Управление изображениями да
Управление файлами да
Webhooks да
Управление пользователями да
Управление доступами пользователей да
Дополнительная информация Очень мощная, есть все фишки уровня enterprice, и даже больше. За счет обилия функционала, нужно чуть больше времени, чтобы в ней разобраться.

Сockpit


Сайт getcockpit.com
Описание Simple Content Platform to manage any structured content
Предназначение Add content management functionality to any site — plug & play / headless / api-first CMS
Целевая аудитория Digital teams
Цена в месяц on-premises — free
Возможность комерческой поддержки да
Подписчиков в twitter 0,7 тыс
Github stars (если open source) 3,5 тыс
Open source решение да
On-premises software да
Cloud service нет
GraphQL API нет, но реализуется через установку аддона
REST API да
Контентная сущность создается на основе модели да
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI да
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) да, при помощи типа repeater
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) да
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) да, при помощи типа repeater
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет, возможно создавать только singleton модели
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) нет
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей да
CRUD API для моделей только read и update
Поддержка API access tokens да
Разграничение прав для доступа к API по API access token да, через настройки collections permssions
Система публикации: Draft/Publish нет
Возможность отсроченной публикации нет
Фиксация версий моделей нет
Фиксация версий контентных сущностей да
Git подобная система версионирования нет
Управление проектами нет, но можно развернуть отдельный экземпляр cms
Управление изображениями да
Управление файлами да
Webhooks да
Управление пользователями да
Управление доступами пользователей да, через конфигурацию групп
Дополнительная информация Достойное opensource решение. Некоторые настройки задаются через конфигурацию, а не через интерфейс. Например, чтобы настроить тип repeater, нужно изучить документацию и прописывать опции через JSON. Написан на PHP.

Cosmic JS


Сайт cosmicjs.com
Описание Modern Content Management Solution. The leading CMS for modern digital teams.
Предназначение The Cosmic JS Headless CMS gives your team everything you need to get the job done.
Целевая аудитория Digital teams, enterprice
Цена в месяц 44$, 179$, 449$, 359$, 719$
Возможность комерческой поддержки да
Подписчиков в twitter 2,8 тыс
Github stars (если open source) не open source
Open source решение нет
On-premises software да
Cloud service да
GraphQL API да
REST API да
Контентная сущность создается на основе модели да, но создатель контента может добавлять любые поля, даже если их нет в модели. Т.е. соответсвие модель -> контент не строгое.
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI да
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) нет, доступны только два варианта:
  • ссылка на любой Object
  • ссылка на Object одного конкретного Object Type

Есть возможнсть создания вложенных моделей (например объект содержит другой объект) да
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) нет
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей да
CRUD API для моделей да
Поддержка API access tokens да
Разграничение прав для доступа к API по API access token да, есть read токен и write токен
Система публикации: Draft/Publish да
Возможность отсроченной публикации да
Фиксация версий моделей нет
Фиксация версий контентных сущностей да
Git подобная система версионирования нет
Управление проектами да
Управление изображениями да
Управление файлами да
Webhooks да
Управление пользователями да
Управление доступами пользователей да

Directus


Сайт directus.io
Описание Premium Open-Source Software For Any Data-Driven Project
Предназначение Directus is an open-source suite of software that provides an instant API wrapper for SQL databases and an intuitive Admin App for non-technical users to manage that content.
Целевая аудитория Digital teams, enterprice
Цена в месяц on-premises — free
Возможность комерческой поддержки да
Подписчиков в twitter 19,4 тыс
Github stars (если open source) 3,8 тыс
Open source решение да
On-premises software да
Cloud service нет, но открыта пре-регистрация
GraphQL API нет
REST API да
Контентная сущность создается на основе модели да
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI да
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) нет
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) нет, есть тип поля group, но через интерфейс сгруппировать поля не удалось
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет, возможно создавать только singleton модели
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) нет
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей да
CRUD API для моделей да
Поддержка API access tokens да, привязываются к пользователю, настраивается через базу данных, а не интерфейс
Разграничение прав для доступа к API по API access token да, через настройку прав пользователя
Система публикации: Draft/Publish нет
Возможность отсроченной публикации нет
Фиксация версий моделей нет
Фиксация версий контентных сущностей да
Git подобная система версионирования нет
Управление проектами нет, но можно развернуть отдельный экземпляр cms
Управление изображениями да
Управление файлами да
Webhooks да, не через интерфейс, описываются на php
Управление пользователями да
Управление доступами пользователей да
Дополнительная информация При изменении модели появлялась ошибка «Something is wrong with this instance’s server or database.» И это блокирует любые манипуляции с типами и сущностями. Встречалось не однозначное поведение. Например есть сущность с текстовым полем и там есть значение длинной 10 символов. Меняем модель — устанавливаем максимальную длинну в 5 символов. Приложение делает вид, что сохранило изменения, но на деле нет. Это видно если повторно открыть настройки. Почему-то не сохраняет сущность если есть поле с русскими буквами. В целом произвело впечатление, что багов довольно много хотя это версия Directus Stable, и это удивило т.к. это зрелый продукт с большим сообществом.

Kentico Cloud


Сайт kenticocloud.com
Описание Stop Your Content Friction. Collaborate and deliver engaging omnichannel experiences with a CMS that's built for content strategists and developers.
Предназначение Create engaging personalized experiences across any device with a next-generation headless CMS.
Целевая аудитория Digital teams, agencies, enterprice
Цена в месяц cloud — 0$, 299$, 999$, hidden price for enterprise
Возможность комерческой поддержки да
Подписчиков в twitter 1 тыс
Github stars (если open source) не open source
Open source решение нет
On-premises software нет
Cloud service да
GraphQL API нет
REST API да
Контентная сущность создается на основе модели да
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI да
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) да
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) нет, подобный функционал реализуется через Content Type Snippets, по сути модель просто ссылается на подмодель, причем snippet не может содержать другой snippet
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) нет
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей да, в professional тарифе
CRUD API для моделей да, только beta версия, в professional тарифе
Поддержка API access tokens да, в professional тарифе
Разграничение прав для доступа к API по API access token да, API token наследует права пользователья, который его сгенерировал
Система публикации: Draft/Publish да
Возможность отсроченной публикации да
Фиксация версий моделей нет
Фиксация версий контентных сущностей да
Git подобная система версионирования нет
Управление проектами да
Управление изображениями да
Управление файлами да
Webhooks да
Управление пользователями да
Управление доступами пользователей да
Дополнительная информация Довольно приятное впечатление, на равне с contentfull. Багов не было все четко и понятно.

Netlify CMS


Сайт netlifycms.org
Описание Open source content management for your Git workflow. Use Netlify CMS with any static site
generator for a faster and more flexible web project
Предназначение Get the speed, security, and scalability of a static site, while still providing a convenient editing interface for content.
Целевая аудитория Profesional developers
Цена в месяц on-premises — free
Возможность комерческой поддержки не анонсирована
Подписчиков в twitter 3,6 тыс
Github stars (если open source) 7,4 тыс
Open source решение да
On-premises software да
Cloud service нет
GraphQL API нет
REST API нет, сохраняет контент в файлы в git репозитории
Контентная сущность создается на основе модели да
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI нет, модели создаются через yml файл
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) нет
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) да, но сущность с полем object не сохраняется в репозиторий, баг
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) нет
Read API для контентных сущностей нет
Ceate, update, delete API для контентных сущностей нет
CRUD API для моделей нет
Поддержка API access tokens нет
Разграничение прав для доступа к API по API access token нет
Система публикации: Draft/Publish да, если editorial_workflow on, поддерживается только на GitHub репозиториях
Возможность отсроченной публикации нет
Фиксация версий моделей да
Фиксация версий контентных сущностей да
Git подобная система версионирования да
Управление проектами нет, но можно развернуть отдельный экземпляр cms
Управление изображениями да, такой раздел есть, но файл не отправляется в репозиторий, баг
Управление файлами да, такой раздел есть, но файл не отправляется в репозиторий, баг
Webhooks нет
Управление пользователями нет, в самой cms нет, но можно управлять пользователями у провайдера git репозитория (в bitbucket, github, gitlab и пр.)
Управление доступами пользователей нет, но можно управлять у провайдера git репозитория
Дополнительная информация Изучал версию — 2.5.1. Эта CMS — оригинальное решение. Это фронтенд приложение, которое использует ваш git репозиторий в качестве бэкенда.

Prismic


Сайт prismic.io
Описание One CMS Backend for all your Websites & Apps
Предназначение CMS for apps, e-commerce, editorial websites, corporate websites. Enables marketing teams to create highly targeted acquisition campaigns.
Целевая аудитория Digital teams, enterprice
Цена в месяц cloud — 0$, 7$, 15$, 100$, 500$
Возможность комерческой поддержки да
Подписчиков в twitter 12,1 тыс
Github stars (если open source) не open source
Open source решение нет
On-premises software нет
Cloud service да
GraphQL API нет, только alpha версия
REST API да
Контентная сущность создается на основе модели да
Есть возможность создавать свои модели да
Есть возможность создавать свои модели через UI да
Модель может содержать ссылку на другую модель да
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) да
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) нет, можно группировать поля при помощи типа «group — a repeatable group of fields», этот тип больше похож на массив, причем group не может содержать другую group
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет, возможно создавать только singleton модели
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) нет возможности создать конфликт, т.к. нельзя задавать настройки валидации полей и указывать какие поля обязательные, а какие нет
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей нет
CRUD API для моделей нет
Поддержка API access tokens да
Разграничение прав для доступа к API по API access token нет (и не требуется, т.к. есть только read)
Система публикации: Draft/Publish да
Возможность отсроченной публикации да
Фиксация версий моделей нет
Фиксация версий контентных сущностей да
Git подобная система версионирования нет
Управление проектами да
Управление изображениями да
Управление файлами да
Webhooks да
Управление пользователями да
Управление доступами пользователей да, в Professional тарифе

Ghost


Сайт ghost.org
Описание Ghost is a fully open source, adaptable platform for building and running a modern online publication. We power blogs, magazines and journalists from Zappos to Sky News.
Предназначение Powerful platform for creating an online blog or publication
Целевая аудитория Professional bloggers, serious enterprise publishers
Цена в месяц on-premises — free; cloud — 29$, 79$, 199$
Возможность комерческой поддержки да
Подписчиков в twitter 24,1 тыс
Github stars (если open source) 28,7 тыс
Open source решение да
On-premises software да
Cloud service да
GraphQL API нет
REST API да
Контентная сущность создается на основе модели нет
Есть возможность создавать свои модели нет
Есть возможность создавать свои модели через UI нет
Модель может содержать ссылку на другую модель нет
Есть возможность комбинировать ссылки (например модель может ссылаться на любую из двух моделей) нет
Есть возможнсть создания вложенных моделей (например объект содержит другой объект) нет
Есть возможность комбинировать модели (например поле может быть или строкой, или числом) нет
Есть возможность указать сколько контентных сущностей может быть создано на основе конкретной модели нет
Управление обнаруженными конфликтами между моделью и контентной сущностью (например, если изменить модель так, чтобы уже существующая контентная сущность не удовлетворяла этим изменениям, умеет ли система решать такие ситуации?) нет
Read API для контентных сущностей да
Ceate, update, delete API для контентных сущностей нет
CRUD API для моделей нет
Поддержка API access tokens да
Разграничение прав для доступа к API по API access token нет
Система публикации: Draft/Publish да
Возможность отсроченной публикации да
Фиксация версий моделей нет
Фиксация версий контентных сущностей нет
Git подобная система версионирования нет
Управление проектами да
Управление изображениями да
Управление файлами нет
Webhooks да
Управление пользователями да
Управление доступами пользователей да
Дополнительная информация Проект вырос из wordpress, мощный editing tool


Выводы


По большому счёту от headless cms я ожидал увидеть две основные вещи: свободу в создании моделей, благодаря чему можно реализовать любой протокол, и git подобную систему контроля версий, чтобы можно было прозрачно управлять всеми изменениями.
И меня ждало легкое разочарование. Хотя с большинством из этих систем можно работать, они обладают рядом неприятных для меня недостатков. Это, конечно, не значит, что системы плохие, это лишь означает, что они не удовлетворили мои ожидания, а мои ожидания — это мои проблемы. Озвучу их:
  • Большинство headless cms поддерживают вложенные структуры данных только через ссылки. Если нужен объект, внутри которого другой объект, то придется создавать две отдельные модели и связывать их через ссылку. Этот принцип оправдан, когда вложенный объект переиспользуется, но если нет, то в системе просто появляется лишняя модель, а за ней и лишние контентные сущности. Такой подход со временем заметно увеличивает и количество моделей, и количество контентных сущностей, что ведет к путанице. Плюс-минус полноценно вложенность поддерживается только в Cloud CMS, Cockpit и Cosmic JS.
  • Иногда требуется комбинировать типы данных: нужно, чтобы свойство объекта было или строкой, или числом. Ну хорошо, в этой ситуации еще можно что-нибудь придумать, в зависимости от конкретного кейса — добавить валидацию при помощи регулярного выражения и нормализовать данные на клиенте. Но что делать, если нужно скомбинировать что-то посложнее, например так:
    {
      "oneOf": [
        { "type": "number", "multipleOf": 5 },
        { "type": "number", "multipleOf": 3 }
      ]
    }
    

    Комбинировать типы данных умеет только Cockpit.
  • Хотелось, чтобы система оповещала о конфликтах между моделью и контентными сущностями. Например, есть модель типа number, у этой модели есть контентная сущность со значением 100. Что произойдет если изменить модель, добавив туда валидацию maximum: 50? Оповестит ли система о конфликте? Такой функционал качественно реализует только GraphCMS.
  • Git подобную систему контроля версий поддерживают только Cloud CMS и Netlify CMS.

К сожалению, когда я работал в той публичной компании, мы так и не смогли взять ни одну из этих систем. Лучше всего под наши потребности подходила Cloud CMS, но и цена на нее кусалась.

Заключение


Вот так этот анализ и привел меня к мысли, что нужно писать свою headless cms. Вы ее уже видели, на ее примере была демонстрация решения задачи. Она называется Any JSON CMS.

Основная ее цель — предоставить свободу в создании сколь угодно сложных моделей и контролировать все изменения при помощи git подобной системы. Сейчас реализовано далеко не все, что хотелось бы, он основной “посыл” уже есть.

Комментарии (9)


  1. a_dubovskoy
    20.03.2019 22:23

    Еще же есть www.contentacms.org. Drupal8 по сути движется в сторону decoupled, www.acquia.com/drupal/decoupled-drupal — смотрите оф.блог Аквии (компании автора Друпала).


    1. a_dubovskoy
      21.03.2019 17:19

      Кстати прямо сейчас JSON:API закоммитили в ядро: dri.es/jsonapi-lands-in-drupal-core


      1. BasilSnowman
        22.03.2019 06:48

        Любопытно, почему не OpenAPI?


        1. a_dubovskoy
          22.03.2019 19:45

          Ну я думаю потому что разработчики проголосовали кодом:
          www.drupal.org/project/openapi — 86 issues, 2,266 сайтов, последний коммит в прошлом году
          www.drupal.org/project/jsonapi — 920 issues, 8,531 сайтов, последний коммит позавчера.


  1. aol-nnov
    21.03.2019 07:13

    А как насчёт вот такой штуки? https://jackrabbit.apache.org/jcr/index.html


    Не рассматривали?


    1. ev-evgeny Автор
      21.03.2019 12:13

      Нет, такую штуку вижу впервые. Вы пользуетесь ей?


      1. aol-nnov
        21.03.2019 12:16

        некоторое время назад делал какое-то подобие cms на ней. вебдав, всё такое… но я на том месте уже не работаю.

        кстати, в фундаменте монстра Alfresco как раз этот заяц заложен.


  1. Arevik
    21.03.2019 14:08

    Не рассматривали? craftercms.org


    1. ev-evgeny Автор
      21.03.2019 21:05

      Нет, такую не рассматривал.