Skip to content

haranton/go-graphql-blog

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

36 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GraphQL: схема и примеры запросов

Схема находится в graph/schema.graphqls. Ниже — примеры типичных запросов, мутаций и подписок.

1) Query — получить все посты

query {
  posts {
    id
    title
    content
    allowComments
  }
}

2) Query — получить пост с комментариями и вложенными ответами

query {
  post(id: "1") {
    id
    title
    content
    comments(limit: 10, offset: 0) {
      id
      content
      parentId
      replies(limit: 5, offset: 0) {
        id
        content
        parentId
      }
    }
  }
}

Описание: Возвращает пост по его id, включая комментарии и вложенные ответы. Уровень вложенности контролирует клиент, добавляя replies в запрос. Для решения проблемы n + 1 есть механизм dataloader.

Параметры пагинации для комментариев:

  • limit — количество элементов на запрос,
  • offset — смещение.

2. Mutation

Все мутации защищены директивой @auth. Для их выполнения пользователь должен быть аутентифицирован (например, через токен, cookie или header).

Создать пост

Запрос:

mutation {
  createPost(title: "Новый пост", content: "Текст поста") {
    id
    title
    content
    allowComments
  }
}

4) Mutation — добавить комментарий

Добавить комментарий

Запрос:

mutation {
  addComment(postId: "1", content: "Отличная статья!") {
    id
    postId
    parentId
    content
  }
}

Описание: Добавляет комментарий к посту. Параметр parentId можно указать, чтобы оставить ответ на другой комментарий.

5) Mutation — запретить комментарии к посту

mutation {
  disallowComments(postId: "1")
}

6) Subscription — получать новые комментарии в реальном времени

subscription {
  commentAdded(postId: "1") {
    id
    postId
    parentId
    content
  }
}

Хранение и запись данных

Сервис поддерживает два типа хранилища:

in-memory (память) — используется по умолчанию, все данные хранятся в оперативной памяти и теряются после перезапуска приложения;

PostgreSQL — используется при запуске с переменной окружения STORAGE=postgres, данные сохраняются на диск и доступны после перезапуска.

Выбор хранилища при запуске

При запуске приложения можно указать тип хранилища через параметр --storage:

In-memory (по умолчанию) go run ./cmd/server --storage=in-memory

PostgreSQL go run ./cmd/server --storage=postgres

Логика записи данных в memory-хранилище

MemoryStorage хранит данные в нескольких структурах:

comments — линейный список всех комментариев в системе

commentByID — быстрый поиск комментария по ID (map[int]*models.Comment)

commentsByPostID — группировка комментариев по постам (map[int][]*models.Comment)

repliesByParentID — иерархия ответов на комментарии (map[int][]*models.Comment)

posts — список всех постов

users — список всех пользователей

postsByID — индекс постов по ID

userBylogin — индекс пользователей по логину

nextCommentID — счетчик для генерации уникальных ID комментариев

Для обеспечения потокобезопасности используется sync.RWMutex.

1. Общие принципы работы

Все объекты (Post, Comment, User) хранятся в оперативной памяти внутри срезов (posts, comments, users).

Для ускорения поиска используются индексы (map), которые позволяют получать данные за O(1).

При создании нового поста или комментария:

  1. генерируется новый ID через счётчики nextPostID или nextCommentID;

  2. объект добавляется в соответствующие коллекции и индексы.

Чтение и запись защищены с помощью sync.RWMutex, что обеспечивает потокобезопасность.

Реализация PostgresStorage обеспечивает сохранение и выборку данных из реляционной базы данных PostgreSQL.
В отличие от MemoryStorage, данные сохраняются на диск и сохраняются между перезапусками приложения.

Для работы используется библиотека sqlx

1. Общие принципы работы

  1. Методы принимают context.Context, что позволяет отменять операции по тайм-ауту или при завершении запроса.
  2. Для вставки данных используется конструкция INSERT ... RETURNING id, чтобы сразу получить ID новой записи.
  3. Для выборки комментариев реализованы методы с фильтрацией (WHERE) и пагинацией (LIMIT, OFFSET).
  4. Для получения комментариев и избежания есть метод ListRepliesBatch чтобы получить комментарии по группе parent id
  5. Добавлены индексы для таблицы comments по post_id и parent_id, и users по полю login для ускорения выборки.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages