[Мессенджеры, JavaScript, Программирование, VueJS] Как создать приложение-чат за двадцать минут (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Мой отец любит напоминать мне, что, будучи компьютерным инженером в 1970-х, «он был программистом до того, как программирование стало модным». Пару раз он даже показывал старые скрипты Fortran и COBOL. Прочитав этот код, я с уверенностью могу сказать, что программирование сегодня определенно круче.
Отличительная черта современных языков программирования и сред разработки — это то, насколько меньше кода приходится писать разработчику. Используя высокоуровневые языки вместе со множеством доступных API-интерфейсов, пакетов с открытым исходным кодом и платных сервисов, приложения — даже со сложными требованиями — можно создавать довольно быстро.
Сравнением, позволяющим продемонстрировать эволюцию разработки программного обеспечения, является строительство. Когда-то строительство любого дома начиналось с вырубки деревьев на вашем участке. Однако быстро появились материалы, инструменты и способы, чтобы строительство завершалось быстрее, объекты становились прочнее, а рабочие освобождались от некоторых элементарных задач.
Сколько было бы построено небоскребов, если бы строители сами добывали себе сталь?
Разработчики ПО, которые продолжают работать и по сей день, на заре карьеры сами “рубили себе деревья”. При этом беспрецедентные инновации последнего десятилетия привели к тому, что индустрия программного обеспечения стала развиваться примерно так же, как и строительство.
Проще говоря, у современных разработчиков теперь есть инструменты, техника и передовые методы, которые позволяют быстрее завершать проекты, получать стабильные приложения, а так же избавляют разработчиков от задач низкого уровня.
Как сделать приложение для чата
Давайте быстро создадим что-нибудь, что раньше занимало бы дни или недели. Мы сделаем Public Chat Room приложение, которое использует WebSockets для обмена сообщениями в реальном времени.
WebSockets нативно поддерживаются всеми современными браузерами. Однако наша цель — выяснить, какие инструменты мы можем использовать в работе, а не изобретать их. Учитывая это, мы будем использовать следующие технологии:
Стартовый проект и полный файл README можно найти в этом репозитории GitHub. Если вы хотите просмотреть только готовое приложение, загляните в ветку public-chat-room.
Кроме того, в видео ниже (на английском языке) более подробно объясняется каждый шаг.
Извините, данный ресурс не поддреживается. :( Начнем.
Семь шагов для создания чат приложения:
1. Настройка проекта
Клонируйте стартовый проект и перейдите в директорию группового чата. Вы можете сами определить, использовать yarn или npm для установки зависимостей проекта. В любом случае, нам нужны все NPM пакеты, обозначенные в файле package.json.
# Клонируем проект
git clone https://github.com/8base/Chat-application-using-GraphQL-Subscriptions-and-Vue.git group-chat
# Переходим в директорию
cd group-chat
# Устанавливаем зависимости
yarn
Чтобы взаимодействовать с GraphQL API, мы должны настроить три переменные среды. Создайте файл .env.local в корневой директории с помощью следующей команды, и приложение Vue после инициализации автоматически установит переменные среды, которые мы добавили в этот файл.
echo 'VUE_APP_8BASE_WORKSPACE_ID=<YOUR_8BASE_WORKSPACE_ID>
VUE_APP_8BASE_API_ENDPOINT=https://api.8base.com
VUE_APP_8BASE_WS_ENDPOINT=wss://ws.8base.com' \
> .env.local
Оба значения VUE_APP_8BASE_API_ENDPOINT и VUE_APP_8BASE_WS_ENDPOINT менять не нужно. Необходимо только установить значение VUE_APP_8BASE_WORKSPACE_ID.
Если у вас есть воркспейс 8base, который вы хотите использовать для создания чат-приложения по нашему руководству, обновите файл .env.local, указав свой идентификатор воркспейса. Если нет — получите идентификатор воркспейса, выполнив шаги 1 и 2 из 8base Quickstart.
2. Импорт схемы
Теперь нам нужно подготовить серверную часть. В корне этого репозитория вы должны найти файл chat-schema.json. Чтобы импортировать его в рабочую область, нужно просто установить командную строку 8base и залогиниться, а затем импортировать файл схемы.
# Установка 8base CLI
yarn global add 8base-cli
# Аутентификация CLI
8base login
# Импортируем схему в нашу рабочую область
8base import -f chat-schema.json -w <YOUR_8BASE_WORKSPACE_ID>
3. Доступ к API
Последняя задача по бэкенду — разрешить публичный доступ к GraphQL API.
В консоли 8base перейдите в App Services > Roles > Guest. Обновите разрешения, установленные как для сообщений, так и для пользователей, чтобы они были или отмечены галочкой, или установлены как All Records (как показано на скриншоте ниже).
Роль Guest определяет, что разрешено делать пользователю, отправившему неаутентифицированный запрос к API.
Редактор ролей в консоли 8base.
4. Пишем GraphQL запросы
На этом этапе мы собираемся определить и выписать все запросы GraphQL, которые нам понадобятся для нашего компонента чата. Это поможет нам понять, какие данные мы будем читать, создавать и прослушивать (через WebSockets) с помощью API.
Следующий код следует поместить в файл src / utils / graphql.js. Прочтите комментарии над каждой экспортированной константой, чтобы понять, что выполняет каждый запрос.
/* gql преобразует строки запроса в документы graphQL */
import gql from "graphql-tag";
/* 1. Получение всех пользователей онлайн-чата и последних 10 сообщений */
export const InitialChatData = gql`
{
usersList {
items {
id
email
}
}
messagesList(last: 10) {
items {
content
createdAt
author {
id
email
}
}
}
}
`;
/* 2. Создание новых пользователей чата и назначение им роли гостя */
export const CreateUser = gql`
mutation($email: String!) {
userCreate(data: { email: $email, roles: { connect: { name: "Guest" } } }) {
id
}
}
`;
/* 3. Удаление пользователя чата*/
export const DeleteUser = gql`
mutation($id: ID!) {
userDelete(data: { id: $id, force: true }) {
success
}
}
`;
/* 4. Подписка на создание и удаление пользователей чата */
export const UsersSubscription = gql`
subscription {
Users(filter: { mutation_in: [create, delete] }) {
mutation
node {
id
email
}
}
}
`;
/* 5. Создание новых сообщений чата и связывание их с автором */
export const CreateMessage = gql`
mutation($id: ID!, $content: String!) {
messageCreate(
data: { content: $content, author: { connect: { id: $id } } }
) {
id
}
}
`;
/* 6. Подписка на создание сообщений чата. */
export const MessagesSubscription = gql`
subscription {
Messages(filter: { mutation_in: create }) {
node {
content
createdAt
author {
id
email
}
}
}
}
`;
5. Настройка Apollo клиента для подписок
Когда наши запросы GraphQL написаны, самое время настроить наши модули API.
Во-первых, давайте займемся клиентом API с помощью ApolloClient с его обязательными настройками по умолчанию. Для createHttpLink мы предоставляем наш полностью сформированный эндпоинт воркспейса. Этот код находится в src/utils/api.js.
import { ApolloClient } from "apollo-boost";
import { createHttpLink } from "apollo-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
const { VUE_APP_8BASE_API_ENDPOINT, VUE_APP_8BASE_WORKSPACE_ID } = process.env;
export default new ApolloClient({
link: createHttpLink({
uri: `${VUE_APP_8BASE_API_ENDPOINT}/${VUE_APP_8BASE_WORKSPACE_ID}`,
}),
cache: new InMemoryCache(),
});
// Note: Чтобы узнать больше о параметрах, доступных при настройке // ApolloClient, обратитесь к их документации.
Затем займемся клиентом подписки, используя subscriptions-transport-ws и isomorphic-ws. Этот код немного длиннее, чем предыдущий, поэтому стоит потратить время на чтение комментариев в коде.
Мы инициализируем SubscriptionClient, используя наш эндопоинт WebSockets и workspaceId в параметрах connectionParams. Затем мы используем этот subscriptionClient в двух методах, определенных в экспорте по умолчанию: subscribe() и close().
subscribe позволяет нам создавать новые подписки с обратными вызовами данных и ошибок. Метод close — это то, что мы можем использовать, чтобы закрыть соединение при выходе из чата.
import WebSocket from "isomorphic-ws";
import { SubscriptionClient } from "subscriptions-transport-ws";
const { VUE_APP_8BASE_WS_ENDPOINT, VUE_APP_8BASE_WORKSPACE_ID } = process.env;
/**
* Создайте клиент подписки, используя соответствующие
*переменные среды и параметры по умолчанию.
*/
const subscriptionClient = new SubscriptionClient(
VUE_APP_8BASE_WS_ENDPOINT,
{
reconnect: true,
connectionParams: {
/**
* Workspace ID ОБЯЗАТЕЛЬНО должен быть установлен, иначе
*конечная точка Websocket не сможет
*сопоставить запрос с соответствующим воркспейсом
*/
workspaceId: VUE_APP_8BASE_WORKSPACE_ID,
},
},
/**
* Конструктор для реализации WebSocket, совместимой с W3C. *Используйте это, если ваше окружение не имеет встроенного собственного *WebSocket (например, с клиентом NodeJS)
*/
WebSocket
);
export default {
/**
* Принимает запрос подписки, любые переменные и обработчики колбэков *'data’ и 'error’
*/
subscribe: (query, options) => {
const { variables, data, error } = options;
/**
* Запускает новый запрос на подписку.
*/
const result = subscriptionClient.request({
query,
variables,
});
/**
* Функцию отписки можно использовать для закрытия *определенной подписки, в отличие от ВСЕХ подписок,
*поддерживаемых subscriptionClient
*/
const { unsubscribe } = result.subscribe({
/**
* При получении события результат передается в
*колбэк данных, указанный разработчиком.
*/
next(result) {
if (typeof data === "function") {
data(result);
}
},
/**
* Каждый раз при получении ошибки она передается в колбэк ошибок, указанный разработчиком.
*/
error(e) {
if (typeof error === "function") {
error(e);
}
},
});
return unsubscribe;
},
/**
* Закрывает subscriptionClient соединение.
*/
close: () => {
subscriptionClient.close();
},
};
// Примечание. Чтобы узнать больше о SubscriptionClient и его параметрах,
// пожалуйста, обратитесь к их документации.
6. Написание компонента Vue
Теперь у нас есть все необходимое для создания публичного чата. Осталось только написать один компонент GroupChat.vue.
Загрузите компонент с помощью yarn serve, и продолжим.
Важное замечание: у каждого свое представление о красоте, поэтому я сделал только минимальные стили, необходимые для того, чтобы компонент был функциональным.
Скрипт компонента
Сначала нам нужно импортировать наши модули, простые стили и GraphQL запросы. Всё это находится в нашем каталоге src / utils.
Объявите следующие импорты в GroupChat.vue.
/* API модули */
import Api from "./utils/api";
import Wss from "./utils/wss";
/* graphQL операции */
import {
InitialChatData,
CreateUser,
DeleteUser,
UsersSubscription,
CreateMessage,
MessagesSubscription,
} from "./utils/graphql";
/* Стили */
import "../assets/styles.css";
Компонентные данные
Мы можем определить, какие свойства данных мы хотим использовать в функции data нашего компонента. Все, что нам нужно, это способ хранить пользователей чата, сообщения, имя «текущего» пользователя и любое сообщение, которое еще не было отправлено. Эти свойства можно добавить следующим образом:
/* imports ... */
export default {
name: "GroupChat",
data: () => ({
messages: [],
newMessage: "",
me: { email: "" },
users: [],
}),
};
Хуки жизненного цикла
Наши хуки жизненного цикла выполняются в разные моменты «жизни» компонента Vue. Например, когда он монтируется или обновляется. В данном случае нас интересует только создание и beforeDestroy компонента. В таких случаях мы хотим либо открыть подписки на чат, либо закрыть.
/* ипорты... */
export default {
/* остальные параметры ... */
/**
* Хук жизненного цикла, выполняющийся при создании компонента.
*/
created() {
/**
* Подписка на событие, которое срабатывает при создании или удалении пользователя
*/
Wss.subscribe(UsersSubscription, {
data: this.handleUser,
});
/**
* Подписка на событие, которое срабатывает при создании сообщения
*/
Wss.subscribe(MessagesSubscription, {
data: this.addMessage,
});
/**
* Получение начальные данные чата (пользователи и последние 10 сообщений)
*/
Api.query({
query: InitialChatData,
}).then(({ data }) => {
this.users = data.usersList.items;
this.messages = data.messagesList.items;
});
/**
* Колбэк вызывается при обновлении страницы, чтобы закрыть чат
*/
window.onbeforeunload = this.closeChat;
},
/**
* Хук жизненного цикла, выполняющийся при уничтожении компонента.
*/
beforeDestroy() {
this.closeChat();
},
};
Методы компонента
Мы должны добавить определенные методы, предназначенные для обработки каждого вызова / ответа API (createMessage, addMessage, closeChat, и т.д.). Все они будут сохранены в объекте методов нашего компонента.
Следует отметить одну вещь: большинство мутаций не ждут и не обрабатывают ответы. Это происходит потому, что у нас работают подписки, которые отслеживают эти мутации. После успешного запуска данные о событиях обрабатываются именно подпиской.
Большинство этих методов говорят сами за себя. В любом случае, прочтите комментарии в следующем коде.
/* импорты ... */
export default {
/* остальные параметры ... */
methods: {
/**
* Создание нового пользователя, используя указанный адрес электронной почты.
*/
createUser() {
Api.mutate({
mutation: CreateUser,
variables: {
email: this.me.email,
},
});
},
/**
* Удалиние пользователя по его ID.
*/
deleteUser() {
Api.mutate({
mutation: DeleteUser,
variables: { id: this.me.id },
});
},
/**
* Наши пользователи подписываются на события создания и обновления, и поэтому
*нам нужно выбрать соответствующий метод для обработки ответа в зависимости от
*типа мутации.
*
*Здесь у нас есть объект, который ищет тип мутации по имени, возвращает
*его и выполняет функцию, передавая узел события.
*/
handleUser({
data: {
Users: { mutation, node },
},
}) {
({
create: this.addUser,
delete: this.removeUser,
}[mutation](node));
},
/**
* Добавляет нового пользователя в массив users, сначала проверяя, *является ли добавляемый пользователь текущим пользователем.
*/
addUser(user) {
if (this.me.email === user.email) {
this.me = user;
}
this.users.push(user);
},
/**
* Удаляет пользователя из массива users по ID.
*/
removeUser(user) {
this.users = this.users.filter(
(p) => p.id != user.id
);
},
/* Создать новое сообщение */
createMessage() {
Api.mutate({
mutation: CreateMessage,
variables: {
id: this.me.id,
content: this.newMessage,
},
}).then(() => (this.newMessage = ""));
},
/**
* Наша подписка на сообщения проверяет только событие создания. *Поэтому все, что нам нужно сделать, это поместить его в наш массив *сообщений.
*/
addMessage({
data: {
Messages: { node },
},
}) {
this.messages.push(node);
},
/**
* Мы хотим закрыть наши подписки и удалить пользователя. Этот метод можно вызвать в нашем хуке жизненного цикла beforeDestroy и любом другом соответствующем колбэке.
*/
closeChat () {
/* Закрытие подписки перед выходом */
Wss.close()
/* Удаление участника */
this.deleteUser();
/* Установка значения по умолчанию */
this.me = { me: { email: '' } }
}
},
/* Хуки ... */
}
Шаблон компонента
И последнее, но не менее важное: у нас есть компонент GroupChat.vue.
Есть тысячи отличных руководств о том, как создавать красивые пользовательские интерфейсы. Это — не одно из них.
Следующий шаблон соответствует минимальным требованиям для чат-приложения. Делать его красивым или нет — это уже ваше дело. Тем не менее, давайте быстро пройдемся по ключевой разметке, которую мы здесь реализовали.
Как всегда, читайте встроенные комментарии к коду.
<template>
<div id="app">
<!--
Представление чата должно отображаться только в том случае, если текущий пользователь имеет идентификатор. В противном случае отображается форма регистрации..
-->
<div v-if="me.id" class="chat">
<div class="header">
<!--
Поскольку мы используем подписки, которые работают в режиме реального времени, количество пользователей, которые сейчас находятся в сети, будет динамически корректироваться.
-->
{{ users.length }} Online Users
<!--
Пользователь может выйти из чата, вызвав функцию closeChat..
-->
<button @click="closeChat">Leave Chat</button>
</div>
<!--
Каждое сообщение, которое мы храним в массиве сообщений, мы будем отображать в этом div. Кроме того, если идентификатор участника сообщения совпадает с идентификатором текущего пользователя, мы присвоим ему класс me.
-->
<div
:key="index"
v-for="(msg, index) in messages"
:class="['msg', { me: msg.participant.id === me.id }]"
>
<p>{{ msg.content }}</p>
<small
><strong>{{ msg.participant.email }}</strong> {{ msg.createdAt
}}</small
>
</div>
<!--
Инпут сообщения привязан к свойству данных newMessage.
-->
<div class="input">
<input
type="text"
placeholder="Say something..."
v-model="newMessage"
/>
<!--
Когда пользователь нажимает кнопку отправки, мы запускаем функцию createMessage.
-->
<button @click="createMessage">Send</button>
</div>
</div>
<!--
Процесс регистрации просит пользователя ввести адрес электронной почты. Как только инпут теряет фокус, вызывается метод createUser.
-->
<div v-else class="signup">
<label for="email">Sign up to chat!</label>
<br />
<input
type="text"
v-model="me.email"
placeholder="What's your email?"
@blur="createUser"
required
/>
</div>
</div>
</template>
И вот публичный чат построен. Если вы откроете его в своей локальной сети, вы сможете начать отправлять и получать сообщения. Однако, чтобы доказать, что это настоящий групповой чат, откройте несколько окон и наблюдайте за ходом разговора.
7. Заключение и тестирование
В этом руководстве мы изучили, как использование современных инструментов разработки позволяет нам создавать реальные приложения за считанные минуты.
Надеюсь, вы также узнали, как инициализировать ApolloClient и SubscriptionClient для эффективного выполнения запросов GraphQL, мутаций и подписок в воркспейсе 8base, а также немного о VueJS.
Независимо от того, работаете ли вы над мобильной игрой, мессенджерами, приложениями-уведомлениями, или над другими проектами, требующими данных в реальном времени, подписки — отличный инструмент. И сейчас мы только начали их рассматривать.
Создайте чат-приложение с 8base
8base — это готовый к работе бессерверный бэкенд-как-сервис, созданный разработчиками для разработчиков. Платформа 8base позволяет разработчикам создавать потрясающие облачные приложения с использованием JavaScript и GraphQL. Узнайте больше о платформе 8base здесь.
===========
Источник:
habr.com
===========
===========
Автор оригинала: Sebastian Scholl
===========Похожие новости:
- [Разработка веб-сайтов, JavaScript, Программирование] Как анимировать элемент «details» с помощью WAAPI (перевод)
- [Программирование, Совершенный код, C++, C] Пока смерть не разлучит нас или всё о static в C++
- [Python, Программирование, Машинное обучение, Искусственный интеллект] Машинное обучение на помощь руководителю разработки
- [Программирование микроконтроллеров, Разработка на Raspberry Pi, DIY или Сделай сам, Здоровье] Затерянные в тумане, или Увлекательные приключения в мире АПР *
- [Maps API, Big Data, Email-маркетинг] Геомаркетинг как инструмент повышения качества проектов
- [Программирование, Интерфейсы, Гаджеты, Компьютерное железо, Научно-популярное] Попытка использовать Raspberry Pi 4 в качестве десктопа. Часть 2, Ubuntu
- [Программирование, Образование за рубежом, Здоровье] Школа 42 как павший воин в эпоху COVID
- [JavaScript, Node.JS] Engine-version — npm пакет, который позволит задать корректное окружение разработки
- [Поисковые технологии, PHP, MySQL, JavaScript, Функциональное программирование] Pick — самая маленькая поисковая система на PHP и MySQL
- [Программирование, Анализ и проектирование систем, Проектирование и рефакторинг] Ценности DDD
Теги для поиска: #_messendzhery (Мессенджеры), #_javascript, #_programmirovanie (Программирование), #_vuejs, #_graphql, #_chat, #_vue, #_websocket, #_8base, #_api, #_messendzhery (
Мессенджеры
), #_javascript, #_programmirovanie (
Программирование
), #_vuejs
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 01:03
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Мой отец любит напоминать мне, что, будучи компьютерным инженером в 1970-х, «он был программистом до того, как программирование стало модным». Пару раз он даже показывал старые скрипты Fortran и COBOL. Прочитав этот код, я с уверенностью могу сказать, что программирование сегодня определенно круче. Отличительная черта современных языков программирования и сред разработки — это то, насколько меньше кода приходится писать разработчику. Используя высокоуровневые языки вместе со множеством доступных API-интерфейсов, пакетов с открытым исходным кодом и платных сервисов, приложения — даже со сложными требованиями — можно создавать довольно быстро. Сравнением, позволяющим продемонстрировать эволюцию разработки программного обеспечения, является строительство. Когда-то строительство любого дома начиналось с вырубки деревьев на вашем участке. Однако быстро появились материалы, инструменты и способы, чтобы строительство завершалось быстрее, объекты становились прочнее, а рабочие освобождались от некоторых элементарных задач. Сколько было бы построено небоскребов, если бы строители сами добывали себе сталь? Разработчики ПО, которые продолжают работать и по сей день, на заре карьеры сами “рубили себе деревья”. При этом беспрецедентные инновации последнего десятилетия привели к тому, что индустрия программного обеспечения стала развиваться примерно так же, как и строительство. Проще говоря, у современных разработчиков теперь есть инструменты, техника и передовые методы, которые позволяют быстрее завершать проекты, получать стабильные приложения, а так же избавляют разработчиков от задач низкого уровня. Как сделать приложение для чата Давайте быстро создадим что-нибудь, что раньше занимало бы дни или недели. Мы сделаем Public Chat Room приложение, которое использует WebSockets для обмена сообщениями в реальном времени. WebSockets нативно поддерживаются всеми современными браузерами. Однако наша цель — выяснить, какие инструменты мы можем использовать в работе, а не изобретать их. Учитывая это, мы будем использовать следующие технологии: Стартовый проект и полный файл README можно найти в этом репозитории GitHub. Если вы хотите просмотреть только готовое приложение, загляните в ветку public-chat-room. Кроме того, в видео ниже (на английском языке) более подробно объясняется каждый шаг. Извините, данный ресурс не поддреживается. :( Начнем. Семь шагов для создания чат приложения: 1. Настройка проекта Клонируйте стартовый проект и перейдите в директорию группового чата. Вы можете сами определить, использовать yarn или npm для установки зависимостей проекта. В любом случае, нам нужны все NPM пакеты, обозначенные в файле package.json. # Клонируем проект
git clone https://github.com/8base/Chat-application-using-GraphQL-Subscriptions-and-Vue.git group-chat # Переходим в директорию cd group-chat # Устанавливаем зависимости yarn Чтобы взаимодействовать с GraphQL API, мы должны настроить три переменные среды. Создайте файл .env.local в корневой директории с помощью следующей команды, и приложение Vue после инициализации автоматически установит переменные среды, которые мы добавили в этот файл. echo 'VUE_APP_8BASE_WORKSPACE_ID=<YOUR_8BASE_WORKSPACE_ID> VUE_APP_8BASE_API_ENDPOINT=https://api.8base.com VUE_APP_8BASE_WS_ENDPOINT=wss://ws.8base.com' \ > .env.local Оба значения VUE_APP_8BASE_API_ENDPOINT и VUE_APP_8BASE_WS_ENDPOINT менять не нужно. Необходимо только установить значение VUE_APP_8BASE_WORKSPACE_ID. Если у вас есть воркспейс 8base, который вы хотите использовать для создания чат-приложения по нашему руководству, обновите файл .env.local, указав свой идентификатор воркспейса. Если нет — получите идентификатор воркспейса, выполнив шаги 1 и 2 из 8base Quickstart. 2. Импорт схемы Теперь нам нужно подготовить серверную часть. В корне этого репозитория вы должны найти файл chat-schema.json. Чтобы импортировать его в рабочую область, нужно просто установить командную строку 8base и залогиниться, а затем импортировать файл схемы. # Установка 8base CLI
yarn global add 8base-cli # Аутентификация CLI 8base login # Импортируем схему в нашу рабочую область 8base import -f chat-schema.json -w <YOUR_8BASE_WORKSPACE_ID> 3. Доступ к API Последняя задача по бэкенду — разрешить публичный доступ к GraphQL API. В консоли 8base перейдите в App Services > Roles > Guest. Обновите разрешения, установленные как для сообщений, так и для пользователей, чтобы они были или отмечены галочкой, или установлены как All Records (как показано на скриншоте ниже). Роль Guest определяет, что разрешено делать пользователю, отправившему неаутентифицированный запрос к API. Редактор ролей в консоли 8base. 4. Пишем GraphQL запросы На этом этапе мы собираемся определить и выписать все запросы GraphQL, которые нам понадобятся для нашего компонента чата. Это поможет нам понять, какие данные мы будем читать, создавать и прослушивать (через WebSockets) с помощью API. Следующий код следует поместить в файл src / utils / graphql.js. Прочтите комментарии над каждой экспортированной константой, чтобы понять, что выполняет каждый запрос. /* gql преобразует строки запроса в документы graphQL */
import gql from "graphql-tag"; /* 1. Получение всех пользователей онлайн-чата и последних 10 сообщений */ export const InitialChatData = gql` { usersList { items { id } } messagesList(last: 10) { items { content createdAt author { id } } } } `; /* 2. Создание новых пользователей чата и назначение им роли гостя */ export const CreateUser = gql` mutation($email: String!) { userCreate(data: { email: $email, roles: { connect: { name: "Guest" } } }) { id } } `; /* 3. Удаление пользователя чата*/ export const DeleteUser = gql` mutation($id: ID!) { userDelete(data: { id: $id, force: true }) { success } } `; /* 4. Подписка на создание и удаление пользователей чата */ export const UsersSubscription = gql` subscription { Users(filter: { mutation_in: [create, delete] }) { mutation node { id } } } `; /* 5. Создание новых сообщений чата и связывание их с автором */ export const CreateMessage = gql` mutation($id: ID!, $content: String!) { messageCreate( data: { content: $content, author: { connect: { id: $id } } } ) { id } } `; /* 6. Подписка на создание сообщений чата. */ export const MessagesSubscription = gql` subscription { Messages(filter: { mutation_in: create }) { node { content createdAt author { id } } } } `; 5. Настройка Apollo клиента для подписок Когда наши запросы GraphQL написаны, самое время настроить наши модули API. Во-первых, давайте займемся клиентом API с помощью ApolloClient с его обязательными настройками по умолчанию. Для createHttpLink мы предоставляем наш полностью сформированный эндпоинт воркспейса. Этот код находится в src/utils/api.js. import { ApolloClient } from "apollo-boost";
import { createHttpLink } from "apollo-link-http"; import { InMemoryCache } from "apollo-cache-inmemory"; const { VUE_APP_8BASE_API_ENDPOINT, VUE_APP_8BASE_WORKSPACE_ID } = process.env; export default new ApolloClient({ link: createHttpLink({ uri: `${VUE_APP_8BASE_API_ENDPOINT}/${VUE_APP_8BASE_WORKSPACE_ID}`, }), cache: new InMemoryCache(), }); // Note: Чтобы узнать больше о параметрах, доступных при настройке // ApolloClient, обратитесь к их документации. Затем займемся клиентом подписки, используя subscriptions-transport-ws и isomorphic-ws. Этот код немного длиннее, чем предыдущий, поэтому стоит потратить время на чтение комментариев в коде. Мы инициализируем SubscriptionClient, используя наш эндопоинт WebSockets и workspaceId в параметрах connectionParams. Затем мы используем этот subscriptionClient в двух методах, определенных в экспорте по умолчанию: subscribe() и close(). subscribe позволяет нам создавать новые подписки с обратными вызовами данных и ошибок. Метод close — это то, что мы можем использовать, чтобы закрыть соединение при выходе из чата. import WebSocket from "isomorphic-ws";
import { SubscriptionClient } from "subscriptions-transport-ws"; const { VUE_APP_8BASE_WS_ENDPOINT, VUE_APP_8BASE_WORKSPACE_ID } = process.env; /** * Создайте клиент подписки, используя соответствующие *переменные среды и параметры по умолчанию. */ const subscriptionClient = new SubscriptionClient( VUE_APP_8BASE_WS_ENDPOINT, { reconnect: true, connectionParams: { /** * Workspace ID ОБЯЗАТЕЛЬНО должен быть установлен, иначе *конечная точка Websocket не сможет *сопоставить запрос с соответствующим воркспейсом */ workspaceId: VUE_APP_8BASE_WORKSPACE_ID, }, }, /** * Конструктор для реализации WebSocket, совместимой с W3C. *Используйте это, если ваше окружение не имеет встроенного собственного *WebSocket (например, с клиентом NodeJS) */ WebSocket ); export default { /** * Принимает запрос подписки, любые переменные и обработчики колбэков *'data’ и 'error’ */ subscribe: (query, options) => { const { variables, data, error } = options; /** * Запускает новый запрос на подписку. */ const result = subscriptionClient.request({ query, variables, }); /** * Функцию отписки можно использовать для закрытия *определенной подписки, в отличие от ВСЕХ подписок, *поддерживаемых subscriptionClient */ const { unsubscribe } = result.subscribe({ /** * При получении события результат передается в *колбэк данных, указанный разработчиком. */ next(result) { if (typeof data === "function") { data(result); } }, /** * Каждый раз при получении ошибки она передается в колбэк ошибок, указанный разработчиком. */ error(e) { if (typeof error === "function") { error(e); } }, }); return unsubscribe; }, /** * Закрывает subscriptionClient соединение. */ close: () => { subscriptionClient.close(); }, }; // Примечание. Чтобы узнать больше о SubscriptionClient и его параметрах, // пожалуйста, обратитесь к их документации. 6. Написание компонента Vue Теперь у нас есть все необходимое для создания публичного чата. Осталось только написать один компонент GroupChat.vue. Загрузите компонент с помощью yarn serve, и продолжим. Важное замечание: у каждого свое представление о красоте, поэтому я сделал только минимальные стили, необходимые для того, чтобы компонент был функциональным. Скрипт компонента Сначала нам нужно импортировать наши модули, простые стили и GraphQL запросы. Всё это находится в нашем каталоге src / utils. Объявите следующие импорты в GroupChat.vue. /* API модули */
import Api from "./utils/api"; import Wss from "./utils/wss"; /* graphQL операции */ import { InitialChatData, CreateUser, DeleteUser, UsersSubscription, CreateMessage, MessagesSubscription, } from "./utils/graphql"; /* Стили */ import "../assets/styles.css"; Компонентные данные Мы можем определить, какие свойства данных мы хотим использовать в функции data нашего компонента. Все, что нам нужно, это способ хранить пользователей чата, сообщения, имя «текущего» пользователя и любое сообщение, которое еще не было отправлено. Эти свойства можно добавить следующим образом: /* imports ... */
export default { name: "GroupChat", data: () => ({ messages: [], newMessage: "", me: { email: "" }, users: [], }), }; Хуки жизненного цикла Наши хуки жизненного цикла выполняются в разные моменты «жизни» компонента Vue. Например, когда он монтируется или обновляется. В данном случае нас интересует только создание и beforeDestroy компонента. В таких случаях мы хотим либо открыть подписки на чат, либо закрыть. /* ипорты... */
export default { /* остальные параметры ... */ /** * Хук жизненного цикла, выполняющийся при создании компонента. */ created() { /** * Подписка на событие, которое срабатывает при создании или удалении пользователя */ Wss.subscribe(UsersSubscription, { data: this.handleUser, }); /** * Подписка на событие, которое срабатывает при создании сообщения */ Wss.subscribe(MessagesSubscription, { data: this.addMessage, }); /** * Получение начальные данные чата (пользователи и последние 10 сообщений) */ Api.query({ query: InitialChatData, }).then(({ data }) => { this.users = data.usersList.items; this.messages = data.messagesList.items; }); /** * Колбэк вызывается при обновлении страницы, чтобы закрыть чат */ window.onbeforeunload = this.closeChat; }, /** * Хук жизненного цикла, выполняющийся при уничтожении компонента. */ beforeDestroy() { this.closeChat(); }, }; Методы компонента Мы должны добавить определенные методы, предназначенные для обработки каждого вызова / ответа API (createMessage, addMessage, closeChat, и т.д.). Все они будут сохранены в объекте методов нашего компонента. Следует отметить одну вещь: большинство мутаций не ждут и не обрабатывают ответы. Это происходит потому, что у нас работают подписки, которые отслеживают эти мутации. После успешного запуска данные о событиях обрабатываются именно подпиской. Большинство этих методов говорят сами за себя. В любом случае, прочтите комментарии в следующем коде. /* импорты ... */
export default { /* остальные параметры ... */ methods: { /** * Создание нового пользователя, используя указанный адрес электронной почты. */ createUser() { Api.mutate({ mutation: CreateUser, variables: { email: this.me.email, }, }); }, /** * Удалиние пользователя по его ID. */ deleteUser() { Api.mutate({ mutation: DeleteUser, variables: { id: this.me.id }, }); }, /** * Наши пользователи подписываются на события создания и обновления, и поэтому *нам нужно выбрать соответствующий метод для обработки ответа в зависимости от *типа мутации. * *Здесь у нас есть объект, который ищет тип мутации по имени, возвращает *его и выполняет функцию, передавая узел события. */ handleUser({ data: { Users: { mutation, node }, }, }) { ({ create: this.addUser, delete: this.removeUser, }[mutation](node)); }, /** * Добавляет нового пользователя в массив users, сначала проверяя, *является ли добавляемый пользователь текущим пользователем. */ addUser(user) { if (this.me.email === user.email) { this.me = user; } this.users.push(user); }, /** * Удаляет пользователя из массива users по ID. */ removeUser(user) { this.users = this.users.filter( (p) => p.id != user.id ); }, /* Создать новое сообщение */ createMessage() { Api.mutate({ mutation: CreateMessage, variables: { id: this.me.id, content: this.newMessage, }, }).then(() => (this.newMessage = "")); }, /** * Наша подписка на сообщения проверяет только событие создания. *Поэтому все, что нам нужно сделать, это поместить его в наш массив *сообщений. */ addMessage({ data: { Messages: { node }, }, }) { this.messages.push(node); }, /** * Мы хотим закрыть наши подписки и удалить пользователя. Этот метод можно вызвать в нашем хуке жизненного цикла beforeDestroy и любом другом соответствующем колбэке. */ closeChat () { /* Закрытие подписки перед выходом */ Wss.close() /* Удаление участника */ this.deleteUser(); /* Установка значения по умолчанию */ this.me = { me: { email: '' } } } }, /* Хуки ... */ } Шаблон компонента И последнее, но не менее важное: у нас есть компонент GroupChat.vue. Есть тысячи отличных руководств о том, как создавать красивые пользовательские интерфейсы. Это — не одно из них. Следующий шаблон соответствует минимальным требованиям для чат-приложения. Делать его красивым или нет — это уже ваше дело. Тем не менее, давайте быстро пройдемся по ключевой разметке, которую мы здесь реализовали. Как всегда, читайте встроенные комментарии к коду. <template>
<div id="app"> <!-- Представление чата должно отображаться только в том случае, если текущий пользователь имеет идентификатор. В противном случае отображается форма регистрации.. --> <div v-if="me.id" class="chat"> <div class="header"> <!-- Поскольку мы используем подписки, которые работают в режиме реального времени, количество пользователей, которые сейчас находятся в сети, будет динамически корректироваться. --> {{ users.length }} Online Users <!-- Пользователь может выйти из чата, вызвав функцию closeChat.. --> <button @click="closeChat">Leave Chat</button> </div> <!-- Каждое сообщение, которое мы храним в массиве сообщений, мы будем отображать в этом div. Кроме того, если идентификатор участника сообщения совпадает с идентификатором текущего пользователя, мы присвоим ему класс me. --> <div :key="index" v-for="(msg, index) in messages" :class="['msg', { me: msg.participant.id === me.id }]" > <p>{{ msg.content }}</p> <small ><strong>{{ msg.participant.email }}</strong> {{ msg.createdAt }}</small > </div> <!-- Инпут сообщения привязан к свойству данных newMessage. --> <div class="input"> <input type="text" placeholder="Say something..." v-model="newMessage" /> <!-- Когда пользователь нажимает кнопку отправки, мы запускаем функцию createMessage. --> <button @click="createMessage">Send</button> </div> </div> <!-- Процесс регистрации просит пользователя ввести адрес электронной почты. Как только инпут теряет фокус, вызывается метод createUser. --> <div v-else class="signup"> <label for="email">Sign up to chat!</label> <br /> <input type="text" v-model="me.email" placeholder="What's your email?" @blur="createUser" required /> </div> </div> </template> И вот публичный чат построен. Если вы откроете его в своей локальной сети, вы сможете начать отправлять и получать сообщения. Однако, чтобы доказать, что это настоящий групповой чат, откройте несколько окон и наблюдайте за ходом разговора. 7. Заключение и тестирование В этом руководстве мы изучили, как использование современных инструментов разработки позволяет нам создавать реальные приложения за считанные минуты. Надеюсь, вы также узнали, как инициализировать ApolloClient и SubscriptionClient для эффективного выполнения запросов GraphQL, мутаций и подписок в воркспейсе 8base, а также немного о VueJS. Независимо от того, работаете ли вы над мобильной игрой, мессенджерами, приложениями-уведомлениями, или над другими проектами, требующими данных в реальном времени, подписки — отличный инструмент. И сейчас мы только начали их рассматривать. Создайте чат-приложение с 8base 8base — это готовый к работе бессерверный бэкенд-как-сервис, созданный разработчиками для разработчиков. Платформа 8base позволяет разработчикам создавать потрясающие облачные приложения с использованием JavaScript и GraphQL. Узнайте больше о платформе 8base здесь. =========== Источник: habr.com =========== =========== Автор оригинала: Sebastian Scholl ===========Похожие новости:
Мессенджеры ), #_javascript, #_programmirovanie ( Программирование ), #_vuejs |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 23-Ноя 01:03
Часовой пояс: UTC + 5