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, criaremos um aplicativo móvel.