GraphQL API

DynapiCMS генерирует GraphQL API из схемы: каждый тип контента получает запросы (чтение), мутации (создание, изменение, удаление), фильтры и сортировку. CRUD писать не нужно.

Эндпоинт: POST /cms/graphql. Playground: GET /cms/playground.

Аутентификация

Каждый запрос к API требует токен или API-ключ:

Способ Заголовок
JWT Authorization: Bearer <jwt>
JWT (alias) Authorization: Token <jwt>
API-ключ X-API-Key: <key>
Cookie auth_token (из логина в админке)

API-ключ также принимается как query-параметр: ?api_key=<key>.

Имена в GraphQL

Slug типа задаёт имена в API. Slug blog-post производит:

Имя Назначение
blogPost(id, slug) Одна запись
blogPosts(where, orderBy, limit, offset) Список
blogPostsCount(where) Количество
createBlogPost(input) Создать
updateBlogPost(id, input) Обновить
deleteBlogPost(id) Удалить

Чтение одной записи

query {
  blogPost(slug: "hello-world") {
    id title status
    author { id name }
  }
}

Аргумент slug доступен только если в типе есть поле slug с флагом Unique. Иначе — только id:

query {
  blogPost(id: "550e8400-e29b-41d4-a716-446655440000") {
    title
  }
}

Локализованные поля возвращаются на языке из аргумента locale или из заголовка X-Locale:

query {
  blogPost(slug: "hello", locale: "ru") {
    title
  }
}

Чтение списка

query {
  blogPosts(limit: 10, offset: 0) {
    id title status
  }
}

limit по умолчанию 10, максимум 100. offset — для пагинации.

Список принимает where (фильтр), orderBy (сортировка), search (поиск) и отдельный blogPostsCount(where) для общего количества. Подробный справочник по всем операторам, комбинаторам и сортировке — на странице Фильтрация и сортировка.

Пример с фильтром и сортировкой:

query {
  blogPosts(
    where: { status: { eq: "published" } }
    orderBy: [{ field: PUBLISHED_AT, direction: DESC }]
  ) { id title }
}

Создание записи

mutation {
  createBlogPost(input: {
    title: "Новый пост"
    slug: "new-post"
    status: "draft"
  }) {
    id title slug
  }
}

Обязательные поля должны быть заполнены. Ссылки передаются по ID:

mutation {
  createBlogPost(input: {
    title: "С автором"
    author: "550e8400-e29b-41d4-a716-446655440000"
  }) { id }
}

Локализованные поля передаются как объект локалей:

mutation {
  createBlogPost(input: {
    title: { ru: "Привет", en: "Hello" }
  }) { id }
}

Обновление записи

Частичное обновление — только переданные поля меняются:

mutation {
  updateBlogPost(
    id: "550e8400-e29b-41d4-a716-446655440000"
    input: { status: "published" }
  ) { id status }
}

Удаление записи

mutation {
  deleteBlogPost(id: "550e8400-e29b-41d4-a716-446655440000")
}

Возвращает true при успехе.

Загрузка медиа

Отдельная мутация для файлов (multipart upload):

mutation($file: Upload!) {
  uploadMedia(file: $file) { id name url mimeType fileSize type }
}

Файл передаётся как multipart form data. Возвращается готовая запись media с ID и URL.

Что дальше