Skip to content

Система для добавления и чтения постов и комментариев с использованием GraphQL

Notifications You must be signed in to change notification settings

ykkssyaa/Posts_Service

Repository files navigation

Posts_Service

Система для добавления и чтения постов и комментариев с использованием GraphQL

Описание задачи

Реализовать систему для добавления и чтения постов и комментариев с использованием GraphQL, аналогичную комментариям к постам на популярных платформах, таких как Хабр или Reddit.

Характеристики системы постов:

  • Можно просмотреть список постов.
  • Можно просмотреть пост и комментарии под ним.
  • Пользователь, написавший пост, может запретить оставление комментариев к своему посту.

Характеристики системы комментариев к постам:

  • Комментарии организованы иерархически, позволяя вложенность без ограничений.
  • Длина текста комментария ограничена до, например, 2000 символов.
  • Система пагинации для получения списка комментариев.

Запуск

Локальный запуск

  1. Клонирование репозитория
  2. make docker.run.db - запуск postgres
  3. make docker.run.migrate - запуск миграций (либо использовать make migrate.up, если утилита golang-migrate установлена локально)
  4. make local.run - локальный запуск сервера

Запуск в Docker

  1. Клонирование репозитория
  2. make docker.run - запуск всех необходимых служб в Docker

В данном случае миграции для базы данных накатятся сами.

Запуск тестов

Для запуска тестов необходимо прописать make tests.run

Остановка работы Docker

Для остановки и удаления контейнеров используйте команду make docker.down

API

API описано в graphqls файлах в директории graph. Запросы были разделены на два домена: посты и комментарии.

Для удобства тестирования сервиса предлагается воспользоваться коллекцией Postman. В коллекции описаны все Queries, Mutations и Subscriptions с возможностью изменения аргументов. Если Postman пользоваться неудобно, то ниже будут примеры запросов.

Для работы с GraphQL была исползована библиоткека gqlgen

Реализованный функционал

Queries

Были реализованы запросы:

  • Получение списка постов с пагинацией (указывается номер и размер страницы)
  • Получение подробной информации о посте с получением комментариев с неограниченной вложеностью и пагинацией

Для решения проблемы N+1 комментарии для поста и ответы на комментарий подгружаются только в том случае, если они запрашиваются в GraphQL запросе.

Mutations

Были реализованы мутации:

  • Создание поста
  • Создание комментария

При создании поста можно указать, разрешены ли для него комментарии. Комментарий создается для конректного поста, при этом он может быть ответом на какой-то другой комментарий. При создании комментария проверяется, можно ли к посту оставлять комментарии.

Subscriptions

Реализована Подписка на комментарии к конкретному посту.

Для управления подписками был реализован CommentObserver, с помощью которого можно создавать, удалять и передавать информацию слушателям.

Слушатели представляют собой структуру из канала для комментариев и идентификатора слушателя. В данной работе не реализована работа с иднетификаторами пользователей, но в перспективе можно создать хранилище, в котором каждый слушатель идентифицируется id поста и id пользователя. Для этого можно реализовать систему аутентификации, к примеру, на основе JWT токенов.

При закрытии контекста подключения слушатель удаляется из хранилища.

Тестирование

Были реализованы unit-тесты для разных слоев программы. Для создания моков я использовал утилиту gomock. Для тестирования я сгенерировал моки для интерфейсов слоёв gateway, service и интерфейса Observers в транспортном слое.

Настроен CI пайплайн запуска тестов и билда приложения на основе GitHub Actions. Каждый коммит и пуллреквест будет проверяться на прохождение всех тестов и сборку. Поэтому, в принципе, нет нужды запускать тесты локально.

Выбор хранилища данных

Есть возможность выбора хранилища для постов и комментариев: либо PostgeSQL, либо самописное in-memory хранилище. При локальном запуске для выбора хранилища необходимо указать в .env файле прописать USE_IN_MEMORY=true для выбора in-memory хранилища. В других случаях будет использоваться PostgreSQL.

В случае с запуском Docker-контейнеров необхолимо прописать то же значение переменной окружения в docker-compose.yml у сервиса app (11 строчка).

Примеры запросов

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

mutation CreatePost {
    CreatePost(
        post: {
            name: "Something Interesting"
            content: "A lot of water"
            author: "Author1"
            commentsAllowed: true
        }
    ) {
        id
        createdAt
        name
        author
        content
    }
}

Получение списка постов

query GetAllPosts {
    GetAllPosts(page: 1, pageSize: 3) {
        id
        createdAt
        name
        author
        content
    }
}

Получение детальной информации о посте

query GetPostById {
    GetPostById(id: 1) {
        id
        createdAt
        name
        author
        content
        commentsAllowed
        comments(page: 1, pageSize: 2) {
            id
            createdAt
            author
            content
            post
            replies {
                id
                createdAt
                author
                content
                post
                replyTo
            }
        }
    }
}

Создание комментария

mutation CreateComment {
    CreateComment(input: { author: "Comm1", content: "WOW", post: "1" }) {
        id
        createdAt
        author
        content
        post
        replyTo
    }
}

Подписка на комментарии поста

subscription CommentsSubscription {
    CommentsSubscription(postId: "1") {
        id
        createdAt
        author
        content
        post
        replyTo
    }
}

About

Система для добавления и чтения постов и комментариев с использованием GraphQL

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published