Há algum tempo, eu estava trabalhando em um aplicativo móvel, cuja funcionalidade incluía um conveniente bate-papo online. E agora decidi escrever um artigo com uma breve instrução sobre como criar um bate-papo usando o servidor apollo e node.js no back-end, bem como reagir o cliente nativo e apollo no lado do cliente.
O artigo está dividido em duas partes para facilitar a leitura. A primeira parte contém um guia para criar um back-end de aplicativo e a segunda contém um guia para criar um front-end de aplicativo.
Se você está com preguiça de ler, pode ver imediatamente o código no Github'e 
aqui e 
aqui .
Como principais tecnologias para implementação, escolhi o framework node.js 
koa , o banco de dados 
postgresql e o servidor GraphQL - 
apollo-server-koa .
Primeiro de tudo, um projeto koa2 vazio foi gerado, para isso usei um simples 
koa-generator executando o comando no terminal:
$ koa <project name> 
Em seguida, as dependências necessárias foram instaladas, eu faço isso com fios, mas você pode usar o npm.
 $ yarn add apollo-server-koa knex objection pg 
Todas as bibliotecas necessárias estão instaladas, agora você pode escrever código
Para conectar-se ao banco de dados, é necessário descrever dois arquivos, o primeiro é o db.js, que exportará a instância do cliente knex e permitirá que nossos modelos trabalhem com dados do banco de dados, o segundo é o knexfile.js, que contém as configurações de conexão com o banco de dados para criar e migrações contínuas.
O código db.js. está descrito abaixo, observe que todas as configurações são obtidas de variáveis de ambiente: const db = require('knex')({ client: 'pg', connection: {   host : process.env.POSTGRES_HOST,   port: process.env.POSTGRES_PORT,   user : process.env.POSTGRES_USER,   password : process.env.POSTGRES_PASSWORD,   database : process.env.POSTGRES_DATABASE } }); module.exports = db; 
O código knexfile.js está disponível 
aqui .
Agora você pode descrever as migrações para criar as duas tabelas necessárias.
As próprias tabelas serão o mais simples possível e conterão apenas o conjunto mínimo de campos necessário. O comando para criá-los está abaixo:
 $ knex migrate:make migration_name 
Você pode ver os arquivos de migração 
aqui .
Agora crie os modelos de entidade Mensagem e Usuário
 class Message extends Model { static get tableName() {   return 'messages'; } $beforeInsert() {   this.created_at = new Date().toISOString(); } static get relationMappings() {   return {     user: {       relation: Model.BelongsToOneRelation,       modelClass: User,       join: {         from: 'messages.user_id',         to: 'users.id'       }     }   }; } } 
A coisa mais interessante permaneceu - conectando e configurando apollo-server-koa, descrição dos esquemas graphql e resolvedores.
Para conectar apollo-server-koa, basta adicionar as seguintes linhas de código
app.js: const { ApolloServer } = require('apollo-server-koa'); const graphqlSchema = require('./graphqlSchema'); … const apolloServer = new ApolloServer(graphqlSchema); apolloServer.applyMiddleware({ app }); 
www: var { app, apolloServer } = require('../app'); ... apolloServer.installSubscriptionHandlers(server); 
Além de conectar o apollo-server-koa, incluímos a capacidade de trabalhar com assinaturas para notificar os clientes que uma nova mensagem chegou no bate-papo.
Apollo-server-koa está conectado, o próximo passo é uma descrição do diagrama graphql com os tipos necessários para o bate-papo
 input UserInput { username: String! } input MessageInput { text: String! user_id: ID! } type User { id: ID username: String } type Message { id: ID text: String created_at: String user: User } type Query { getLast100Messages: [Message] } type Mutation { findOrCreateUser(user: UserInput!): User createMessage(message: MessageInput!): Message } type Subscription { messageCreated: Message } 
O circuito está pronto, descrevemos os resolvedores
Um exemplo de resolvedor para enviar uma nova mensagem: const Message = require('../../models/message'); const { pubsub, MESSAGE_CREATED } = require('../../utils'); module.exports = { createMessage: async (obj, { message }, context, info) => {   const createdMessage = await Message     .query()     .insert(message);   const resultMessage = await Message     .query()     .eager('user')     .findById(createdMessage.id);   pubsub.publish(MESSAGE_CREATED, { messageCreated: resultMessage });   return resultMessage; }, }; 
Um ponto interessante é que, além de salvar a mensagem no banco de dados, a função publish () é chamada aqui, que notifica todos os assinantes sobre o evento MESSAGE_CREATED, enviando a eles o objeto de uma nova mensagem (o leitor atento notará que o remetente também será notificado de sua nova mensagem e continuaremos processando isso mais adiante) para o cliente, em um projeto real, faz sentido processar isso no lado de back-end, para não duplicar a lógica entre diferentes clientes).
O código dos resolvedores restantes pode ser encontrado 
aqui .
O lado do servidor do bate-papo está pronto. Como posso verificar se tudo está funcionando?
Abra o 
host no seu navegador e você verá o playground graphql nele.
 Na próxima parte,
Na próxima parte, criaremos um aplicativo móvel.