GraphQL Subscriptions: Integrações Reativas e em Tempo Real
A integração de sistemas em tempo real é cada vez mais crucial para aplicações modernas. GraphQL, com suas consultas precisas e tipagem forte, oferece uma alternativa poderosa às APIs REST tradicionais. No entanto, GraphQL originalmente se concentrava em consultas e mutações, deixando a comunicação em tempo real a cargo de outras tecnologias. É aí que entram as GraphQL Subscriptions.
GraphQL Subscriptions permitem que o servidor notifique o cliente sobre eventos específicos que ocorrem no backend. Isso possibilita a criação de interfaces de usuário reativas, dashboards dinâmicos e notificações push em tempo real, tudo mantendo a eficiência e a flexibilidade do GraphQL.
O que são GraphQL Subscriptions?
Subscriptions são uma extensão da especificação GraphQL que permite que os clientes “assinem” eventos no servidor. Quando um evento relevante ocorre (por exemplo, um novo comentário é adicionado a um post, um pedido é atualizado, ou um novo usuário se registra), o servidor envia uma atualização para todos os clientes que assinaram aquele evento. A comunicação geralmente é estabelecida através de WebSockets ou Server-Sent Events (SSE).
Implementando GraphQL Subscriptions com Node.js e Apollo Server
Vamos construir um exemplo prático usando Node.js, Apollo Server e um banco de dados PostgreSQL para demonstrar o uso de GraphQL Subscriptions.
Pré-requisitos:
- Node.js instalado
- npm ou yarn
- PostgreSQL instalado
- Conhecimento básico de GraphQL
Passo 1: Configurando o Projeto
Crie um novo diretório para o seu projeto e inicialize um projeto Node.js:
mkdir graphql-subscriptions-example
cd graphql-subscriptions-example
npm init -y
Instale as dependências necessárias:
npm install apollo-server graphql pg graphql-subscriptions
Passo 2: Definindo o Schema GraphQL
Crie um arquivo chamado schema.graphql com o seguinte conteúdo:
type Post { id: ID! title: String! content: String! }type Query { posts: [Post!]! }
type Mutation { createPost(title: String!, content: String!): Post! }
type Subscription { postCreated: Post! }
Passo 3: Implementando os Resolvers
Crie um arquivo chamado resolvers.js com o seguinte conteúdo:
const { PubSub } = require('graphql-subscriptions'); const { Pool } = require('pg');const pubsub = new PubSub();
const pool = new Pool({ user: 'seu_usuario', host: 'localhost', database: 'seu_banco_de_dados', password: 'sua_senha', port: 5432, });
const POST_CREATED = 'POST_CREATED';
const resolvers = { Query: { posts: async () => { const { rows } = await pool.query('SELECT * FROM posts'); return rows; }, }, Mutation: { createPost: async (_, { title, content }) => { const { rows } = await pool.query( 'INSERT INTO posts (title, content) VALUES ($1, $2) RETURNING *', [title, content] ); const newPost = rows[0]; pubsub.publish(POST_CREATED, { postCreated: newPost }); return newPost; }, }, Subscription: { postCreated: { subscribe: () => pubsub.asyncIterator([POST_CREATED]), }, }, };
module.exports = resolvers;
Explicação do código:
PubSubé usado para publicar e assinar eventos.Poolé usado para conectar ao banco de dados PostgreSQL.- O resolver
createPostpublica um eventoPOST_CREATEDapós criar um novo post. - O resolver
postCreateddefine a funçãosubscribeque retorna um iterador assíncrono para o eventoPOST_CREATED.
Passo 4: Configurando o Apollo Server
Crie um arquivo chamado index.js com o seguinte conteúdo:
const { ApolloServer } = require('apollo-server'); const { PubSub } = require('graphql-subscriptions'); const { readFileSync } = require('fs'); const resolvers = require('./resolvers');const typeDefs = readFileSync('./schema.graphql', { encoding: 'utf-8' });
const pubsub = new PubSub();
const server = new ApolloServer({ typeDefs, resolvers, context: { pubsub }, subscriptions: { onConnect: (connectionParams, webSocket) => { console.log('Client connected'); }, onDisconnect: (webSocket, context) => { console.log('Client disconnected') }, }, });
server.listen().then(({ url, subscriptionsUrl }) => { console.log(🚀 Server ready at ${url}); console.log(🚀 Subscriptions ready at ${subscriptionsUrl}); });
Explicação do código:
- Lê o schema GraphQL do arquivo
schema.graphql. - Cria uma instância do
ApolloServercom ostypeDefseresolvers. - Configura as subscriptions, incluindo os callbacks
onConnecteonDisconnect. - Inicia o servidor e exibe as URLs para acessar a API e as subscriptions.
Passo 5: Criando a Tabela no PostgreSQL
Execute o seguinte comando SQL para criar a tabela posts no seu banco de dados PostgreSQL:
CREATE TABLE posts (
id SERIAL PRIMARY KEY,
title VARCHAR(255) NOT NULL,
content TEXT NOT NULL
);
Passo 6: Executando o Servidor
Execute o seguinte comando para iniciar o servidor:
node index.js
O servidor estará disponível em http://localhost:4000 e as subscriptions em ws://localhost:4000/graphql.
Passo 7: Testando as Subscriptions
Você pode usar o Apollo Client ou qualquer cliente GraphQL para testar as subscriptions. Aqui está um exemplo de consulta de subscription:
subscription {
postCreated {
id
title
content
}
}
E uma mutation para criar um novo post:
mutation {
createPost(title: "Novo Post", content: "Conteúdo do novo post") {
id
title
content
}
}
Alternativas e Frameworks
Além do Apollo Server, existem outras opções para implementar GraphQL Subscriptions, como:
- GraphQL Yoga: Um servidor GraphQL leve e fácil de usar.
- Strawberry: Uma biblioteca GraphQL para Python que suporta subscriptions.
- Hasura: Uma plataforma que gera automaticamente APIs GraphQL a partir de bancos de dados PostgreSQL, com suporte integrado para subscriptions.
Casos de Uso
GraphQL Subscriptions são ideais para diversas aplicações, incluindo:
- Chat em tempo real: Notificar os usuários quando novas mensagens são enviadas.
- Notificações push: Enviar notificações para os usuários quando eventos importantes ocorrem.
- Dashboards dinâmicos: Atualizar os dashboards em tempo real com dados do backend.
- Jogos multiplayer: Sincronizar o estado do jogo entre os jogadores em tempo real.
Considerações de Performance e Escalabilidade
Ao implementar GraphQL Subscriptions, é importante considerar a performance e a escalabilidade. Algumas dicas incluem:
- Usar um broker de mensagens: Para distribuir os eventos entre múltiplos servidores, use um broker de mensagens como Redis ou RabbitMQ.
- Otimizar as consultas: Certifique-se de que as consultas GraphQL são otimizadas para evitar gargalos de performance.
- Monitorar o sistema: Monitore o sistema para identificar e resolver problemas de performance.
Integração com outras tecnologias
GraphQL Subscriptions podem ser integradas com outras tecnologias para criar soluções mais robustas e flexíveis. Por exemplo:
- Bancos de dados em tempo real: Integração com bancos de dados como Firebase ou Supabase para atualizações em tempo real.
- Serviços de mensageria: Utilização de serviços como Kafka ou RabbitMQ para gerenciar o fluxo de eventos.
- Plataformas serverless: Implantação de subscriptions em plataformas serverless como AWS Lambda ou Google Cloud Functions.
Conclusão
GraphQL Subscriptions oferecem uma maneira poderosa e eficiente de criar integrações reativas e em tempo real. Ao usar GraphQL Subscriptions, você pode construir aplicações mais dinâmicas e responsivas, melhorando a experiência do usuário e aumentando a eficiência do seu negócio. Com as ferramentas e técnicas certas, você pode aproveitar ao máximo o potencial das GraphQL Subscriptions e criar soluções inovadoras e escaláveis.

