Принесите магию RethinkDB в реальном времени во фронтенд с помощью GraphQL

В недавнем посте мы исследовали, как встроенная реактивность RethinkDB идеально подходит для написания чат-приложения с Socket.io. В этой статье вы узнаете, как вместо этого использовать подписки GraphQL, чтобы получить доступ к реактивной природе RethinkDB во внешнем интерфейсе.

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

Вы также можете попробовать работающее приложение или заглянуть в репозиторий кода.

Настройка приложения

Мы создадим приложение Node.js, поэтому вам необходимо установить node и npm. Если вы хотите развернуть свое приложение на Heroku, вам также понадобится учетная запись Heroku, а также установлен их CLI. Чтобы запустить приложение локально, вам необходимо установить и запустить экземпляр RethinkDB.

Мы будем использовать простой сервер Node.js и внешний интерфейс Vue.js. Поскольку интерфейс необходимо построить, мы создадим приложение Vue с Vue CLI:

$ vue create -d rethink-chat
$ cd rethink-chat

Это создаст проект Node, создаст скелет Vue.js и инициализирует репозиторий git.

Подготовьте приложение Heroku

Чтобы развернуть приложение на Heroku, нам нужно создать приложение Heroku:

$ heroku create

Нам также понадобится экземпляр RethinkDB для хранения и подписки на сообщения чата, отправляемые между пользователями. Сделать это можно через надстройку RethinkDB Cloud следующим образом:

$ heroku addons:create rethinkdb

Надстройка RethinkDB Cloud в настоящее время находится на стадии альфа-тестирования. Запросите приглашение на электронную почту вашего аккаунта Heroku.

Сборка сервера

Мы создадим наш сервер в каталоге server. Итак, для начала давайте создадим каталог и установим необходимые зависимости:

$ mkdir server
$ npm install rethinkdb apollo-server-express graphql morgan lorem-ipsum

Теперь давайте настроим сервер Node.js. Создайте файл index.js и добавьте следующий каркас сервера. Мы используем сервер Express.js для обслуживания внешнего интерфейса и сервер Apollo GraphQL для доступа и подписки на сообщения чата.

Этот скелет обслуживает статический интерфейс из папки dist. Здесь находится скомпилированное приложение Vue.js, которое мы создадим позже. Кроме того, наш сервер должен делать три вещи:

  1. Обработка подключений к базе данных RethinkDB
  2. Настройте сервер Apollo
  3. Создайте схему GraphQL, включая определения типов и преобразователи

RethinkDB соединение

Мы лениво управляем нашим подключением к RethinkDB, т.е. мы создаем (повторное) подключение только тогда, когда оно действительно необходимо. Параметры подключения извлекаются из переменных среды или используются значения по умолчанию.

На Heroku надстройка RethinkDB Cloud устанавливает переменные среды. Для локально запущенного экземпляра RethinkDB должны работать значения по умолчанию.

Настройка сервера Apollo GraphQL

Как упоминалось ранее, интерфейс статичен. Однако нам нужен доступ к данным в чате. Этим займется Apollo, наиболее часто используемый сервер GraphQL.

Это создаст сервер Apollo с использованием определений типов и разрешений, определенных в нашем файле схемы (следующий раздел). Мы также подключаемся к RethinkDB и передаем соединение нашему контексту GraphQL, чтобы его можно было использовать в любом входящем запросе.

Создать схему GraphQL

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

  • Запрос сообщений чата в комнате
  • Отправить сообщение чата в комнату
  • Подпишитесь на новые сообщения чата в комнате

Сначала мы создаем типы GraphQL. Он состоит из типа сообщения Chat и трех упомянутых действий, а именно запроса chats, мутации sendChat и подписки chatAdded.

Во-вторых, нам нужно разрешить эти действия, то есть реализовать код, который они вызывают. Запрос и изменение довольно просты и реализованы как простой запрос RethinkDB. Однако для подписки требуется асинхронный итератор. По сути, это заклинание, превращающее магию RethinkDB в магию подписки GraphQL. Говоря более земным языком, асинхронный итератор является оболочкой для ленты изменений RethinkDB, поэтому мы можем подписаться на него через GraphQL.

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

Создание интерфейса

Мы уже создали скелет приложения Vue.js, который мы будем использовать для внешнего интерфейса. Однако, поскольку наш сервер реализует стандартный бэкэнд GraphQL, вы также можете использовать React или любую другую платформу внешнего интерфейса, поддерживающую GraphQL.

Наш интерфейс будет использовать два представления, одно для домашней страницы и одно для комнаты чата, а также маршрутизатор для навигации между ними. Для этого добавим маршрутизатор в каркас Vue и установим все необходимые зависимости. Добавление маршрутизатора в приложение Vue предупредит вас о незавершенных изменениях (все равно продолжить) и спросит, нужен ли вам режим истории (нет).

$ vue add router
$ npm install apollo-client apollo-link-http apollo-link-ws apollo-cache-inmemory vue-apollo
$ npm install sass sass-loader --save-dev

Наше приложение Vue находится в папке src и будет иметь следующую структуру: точка входа находится в main.js и получает конфигурацию клиента GraphQL от graphql.js. Наш основной файл также монтирует App.vue, который отображает виды, выбранные маршрутизатором в router/index.js. Наше приложение содержит два представления: views/Home.vue и views/ChatRoom.vue.

src
├── main.js
├── graphql.js
├── App.vue
├── router
│   └── index.js
└── views
    ├── Home.vue
    └── ChatRoom.vue

Основное приложение и роутер

На первом этапе давайте изменим файлы основного приложения, домашнего представления и маршрутизатора, которые были инициализированы в скелетном приложении Vue. В main.js мы импортируем клиент Apollo GraphQL, который определим ниже, и добавим его в наше приложение Vue. Кроме того, мы также создадим случайное имя пользователя в чате для пользователя.

Наш App.vue даже проще, чем скелет, он просто показывает вид маршрутизатора и имеет некоторый стиль.

В нашем router/index.js мы в основном заменяем маршрут «О программе» маршрутом «Комната».

В домашнем представлении мы удаляем компонент HelloWorld и добавляем форму, которая позволяет нам присоединиться к комнате.

Теперь, когда мы наполнили скелет необходимыми частями, давайте займемся реальной составляющей внешнего интерфейса, клиента GraphQL и представления комнаты чата.

Клиент GraphQL

Когда наш интерфейс загружается, нам нужно запустить клиент GraphQL. В нашем примере мы используем Apollo, наиболее часто используемый клиент GraphQL, который имеет хорошую интеграцию Vue.js с пакетом vue-apollo.

Поскольку мы будем использовать подписки GraphQL, наша установка Apollo немного сложнее, чем обычно. Это связано с тем, что обычный GraphQL должен выполняться через HTTP, но обновления подписки будут передаваться через WebSocket.

Вид комнаты чата

Последней частью внешнего интерфейса будет представление ChatRoom. Здесь мы фактически можем использовать только что инициализированный клиент GraphQL. Это представление в основном показывает список со всеми элементами в переменной chats и предоставляет форму для отправки сообщения чата на серверную часть.

Метод sendMessage связан с мутацией sendChat GraphQL. Что касается переменной chats, привязка немного сложнее. Мы привязываем его к запросу GraphQL chats и, кроме того, используем подписку chatAdded, чтобы поддерживать переменную в актуальном состоянии.

Теперь у нас есть рабочий сервер и фронтенд. Последнее, что нам нужно, это убедиться, что таблица chats действительно существует в базе данных RethinkDB при запуске приложения.

Перенос базы данных

Приложение не работает без chats таблицы. Таким образом, нам нужна миграция базы данных, которая добавляет таблицу.

Эта миграция проверяет, существует ли таблица chats, и, если она отсутствует, создает ее.

Простой чат-бот

Как мы видели, одна из замечательных функций RethinkDB - это встроенная реактивность, которая позволяет нам подписываться на запросы. Эта функция также пригодится при создании простого чат-бота. Бот просто должен подписаться на изменения в таблице chats и реагировать на них, когда это необходимо.

Наш бот Lorem ответит случайным разделом Lorem Ipsum всякий раз, когда будет предложено @lorem. Бот подписывается на chats таблицу и сканирует начало сообщения. Если он начинается с@lorem, он ответит сообщением в той же комнате.

Разверните приложение на Heroku

Чтобы развернуть наше рабочее приложение и бота на Heroku, нам нужно создать Procfile. Этот файл в основном сообщает Heroku, какие процессы запускать.

// Procfile
release: node server/migrate.js
web: node server/index.js
lorem-bot: node server/lorem-bot.js

Процессы release и web распознаются Heroku как команда, запускаемая при выпуске, и как основное веб-приложение соответственно. lorem-bot процесс - это просто рабочий процесс, который может иметь любое имя.

Разверните приложение в Heroku с помощью

$ git add .
$ git commit -m 'Working rethink-chat app'
$ git push heroku master

Вам нужно будет вручную включить процесс lorem-bot в вашем приложении Heroku. Вы можете сделать это на вкладке "Ресурсы".

Заключение

Менее чем за 15 минут нам удалось создать и развернуть чат-приложение с помощью простого бота. Это показывает мощность и простоту использования RethinkDB. Возможность подписаться на запросы упрощает создание реактивного приложения и может быть легко интегрирована с GraphQL. Кроме того, Heroku упрощает развертывание, а с надстройкой RethinkDB Cloud вам никогда не придется выполнять утомительную работу по управлению сервером базы данных самостоятельно.

Первоначально опубликовано на https://www.rethinkdb.cloud 3 сентября 2020 г.

JavaScript на простом английском языке

Вы знали, что у нас есть три публикации и канал на YouTube? Найдите ссылки на все на plainenglish.io!