разработка

RocketCMS: Headless CMS без моделей на Rust

Дата публикации

ℹ️

🚀 Что covered в этом посте

RocketCMS — активный проект разработки - headless CMS на базе Rust с радикальной философией: ноль встроенных моделей. Пользователи определяют всё через схемы JavaScript, совместимые с Strapi, выполняемые через QuickJS, с API, миграциями и таблицами базы данных, генерируемыми автоматически.

Ноль моделей, бесконечные возможности

Большинство платформ CMS имеют мнение. Они дают вам пользователей, страницы, посты, медиатеки — всё предварительно построено, всё жёсткое. RocketCMS принимает другой подход: вы определяете всё.

Февраль 2026

Фаза 0 завершена: Основание + Схема работает. Проект теперь имеет работающий парсер схем, систему миграции и динамическую генерацию API.

Философия

ℹ️

📦 Традиционная CMS

  • Предварительно построенные модели пользователей
  • Фиксированные типы контента
  • Жёсткие отношения
  • Мнение о структуре
ℹ️

✨ RocketCMS

  • Ноль встроенных моделей
  • Схемы, определяемые JavaScript
  • Динамическая генерация миграций
  • Ваша структура, ваши правила

Обзор архитектуры

RocketCMS построен на проверенной инфраструктуре Rust:

Основной стек

  • Axum 0.7 - Web-фреймворк с поддержкой async
  • SeaORM 1.1 - Database ORM с динамическими возможностями
  • Tokio - Async runtime
  • rquickjs - Движок JavaScript QuickJS
  • PostgreSQL / SQLite - Database backends

Определение схем в JavaScript

Схемы определяются с использованием файлов JavaScript, совместимых со Strapi. Это был намеренный выбор — он делает миграцию со Strapi тривиальной и даёт пользователям знакомый синтаксис.

// schemas/article.js
module.exports = {
  kind: 'collectionType',
  collectionName: 'articles',
  info: {
    singularName: 'article',
    pluralName: 'articles',
    displayName: 'Article',
  },
  attributes: {
    title: {
      type: 'string',
      required: true,
      maxLength: 200,
    },
    slug: {
      type: 'uid',
      targetField: 'title',
    },
    content: {
      type: 'richtext',
    },
    published: {
      type: 'boolean',
      default: false,
    },
    author: {
      type: 'relation',
      relation: 'manyToOne',
      target: 'api::user.user',
      inversedBy: 'articles',
    },
  },
};

✅ Ключевое решение: rquickjs вместо Boa

Проект использует rquickjs (QuickJS) вместо Boa для выполнения JavaScript. Причина: лучшая поддержка ES-модулей и меньший footprint, что важно при выполнении пользовательского кода во время выполнения.

Динамическая система схем

Когда RocketCMS запускается, он:

  1. Загружает файлы схем из ./src/schemas/*.js
  2. Выполняет их через движок QuickJS
  3. Парсит вывод во внутренние структуры Rust
  4. Генерирует миграции для любых изменений схемы
  5. Создаёт API-маршруты автоматически
⚠️

⚠️ Исследование SeaORM Dynamic

Ключевой вопрос во время разработки: может ли SeaORM обрабатывать действительно динамические модели без генерации кода? Ответ: да. SeaORM поддерживает выполнение необработанного SQL и динамический доступ к столбцам, что делает его идеальным для приложений, управляемых схемой.

Статус текущей реализации

✅ Фаза 0: Основание

  • Проект инициализирован
  • Axum + SeaORM настроены
  • Database connections работают
  • 107 Rust тестов проходят
  • 44 JavaScript vitest тестов проходят

✅ Фаза 1: Система схем

  • Парсер схем реализован
  • Обёртка движка rquickjs
  • Валидация схем через Serde
  • Загрузчик схем с file watching

✅ Фаза 2: Миграции

  • Запуск миграций с 19 тестами
  • Таблица отслеживания схем
  • Динамический построитель запросов
  • Все обработчики CRUD реализованы

✅ Фаза 3: Генерация API

  • Динамическая генерация маршрутов
  • Валидация запросов с garde
  • Поддержка пагинации
  • Сериализация ответов

Работающие API-маршруты

Сервер теперь генерирует эти маршруты автоматически из схем:

Автоматически сгенерированные endpoints

  • GET /health - Проверка работоспособности
  • GET /api/health - Проверка работоспособности API
  • GET /api/companies - Список компаний
  • GET /api/pages - Список страниц
  • GET /api/categories - Список категорий
  • POST /api/{collection} - Создание элемента
  • GET /api/{collection}/:id - Чтение элемента
  • PATCH /api/{collection}/:id - Обновление элемента
  • DELETE /api/{collection}/:id - Удаление элемента

Дорожная карта: что дальше

Временная линия реализации

  1. Фаза 4: Аутентификация — Управление пользователями, JWT-токены, хеширование паролей, интеграция OIDC и SAML (вероятно, через Keycloak)
  2. Фаза 5: Админ-интерфейс — React SPA с Vite для управления схемами, просмотра данных, редактирования контроля доступа и управления пользователями
  3. Фаза 6: Тестовый фреймворк — Browser-тесты с Chromiumoxide, самотесты при загрузке и комплексное покрытие тестами
  4. Фаза 7: Управление приложениями frontend — Загрузка/выгрузка frontend-приложений как ZIP-файлов, интеграция с Git через Gitoxide, генерация Docker Compose и встроенная IDE
  5. Фаза 8: Система плагинов — API плагинов на основе FFI, динамическая загрузка, управление жизненным циклом и изоляция ошибок

Технические моменты

ℹ️

⚡ Динамический ORM

// Выполняем DDL динамически
db.execute(Statement::from_string(
    sea_orm::DatabaseBackend::Sqlite,
    "CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)"
)).await?;

// Запрос с динамическими результатами
let results = db.query_all(Statement::from_string(
    sea_orm::DatabaseBackend::Sqlite,
    "SELECT * FROM users".to_string(),
)).await?;
ℹ️

🔧 Сопоставления типов

Attribute TypeSQLite Type
String, EmailTEXT
IntegerINTEGER
BooleanINTEGER (1/0)
DateTimeTEXT (ISO8601)
Json, EnumTEXT (JSON)

Статус разработки

ℹ️

📊 Текущие метрики

  • Репозиторий: /data/rocketcms/
  • Тесты: 107 Rust тестов + 44 JavaScript тестов проходят
  • Фазы завершены: 0-3 (Основание через генерацию API)
  • Статус сервера: Работает на 127.0.0.1:8080
  • Статус: Активная разработка

Почему этот подход важен

Блокировка традиционных CMS исходит из их предварительно построенных предположений. Делая всё определяемым пользователем, RocketCMS достигает:

Преимущества

  • Нет блокировки пути миграции - Принесите свои схемы Strapi
  • Нет мнения о моделях данных - Структурируйте то, что вам нужно
  • Нет пересборки для изменений - Схемы загружаются во время выполнения
  • Нет жёстких отношений - Определяйте что имеет смысл
  • Нет потолка абстракции - Полная производительность Rust с эргономикой JavaScript

🚀 Готовы исследовать?

RocketCMS в активной разработке, с фазами 0-3 завершёнными и доказывающими, что основная концепция работает. Проект демонстрирует, что Rust может доставить безопасность и производительность системного языка при обеспечении эргономики разработчика определения схем JavaScript.

Далее: Аутентификация, админ-интерфейс и перевод проекта от концепт-пруф до production-ready.

#текущая работа#rust#headless-cms#strapi#axum#seaorm#quickjs#web-development