0Pricing
GraphQL APIs with Spring Boot · Aula

Implementando Atualizações em Tempo Real

Desenvolva resolvedores de assinatura no Spring Boot para publicar eventos e enviar dados em tempo real aos clientes.

Implementando Atualizações em Tempo Real é uma aula grátis de GraphQL APIs with Spring Boot no CoddyKit. Esta é a aula 2 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de GraphQL APIs with Spring Boot, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de GraphQL APIs with Spring Boot inclui 4 aulas no total.

Partes desta aula ainda não foram traduzidas e aparecem em inglês.

Subscription Resolvers Explained

Subscriptions deliver real-time updates. Unlike queries that return data once, subscription resolvers return a stream of data that continuously pushes updates to clients.

We'll learn how to implement these streams in a Spring Boot GraphQL application.

Embracing Reactor Flux

Spring GraphQL leverages Project Reactor's Flux to handle subscriptions. A Flux represents an asynchronous, non-blocking stream of 0 to N items.

  • It's ideal for continuous data delivery.
  • You can emit multiple values over time.

Schema for Real-time Updates

First, we define our subscription in the GraphQL Schema Definition Language (SDL). This example shows a subscription for new messages:

type Subscription {
  messageAdded(channelId: ID!): Message
}

type Message {
  id: ID!
  text: String!
  channelId: ID!
  timestamp: String!
}

Creating a Subscription Resolver

In Spring Boot, a subscription resolver is a method annotated with @SubscriptionMapping. It must return a Flux of the desired type.

We'll use a Sinks.Many to manage and publish events into this stream.

import org.springframework.graphql.data.method.annotation.SubscriptionMapping;
import org.springframework.stereotype.Controller;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Sinks;

@Controller
public class MessageSubscriptionController {

    private final Sinks.Many<Message> messageSink = 
        Sinks.many().multicast().onBackpressureBuffer();

    @SubscriptionMapping
    public Flux<Message> messageAdded() {
        return messageSink.asFlux();
    }
}

Publishing Events with Sinks.Many

The Sinks.Many instance acts as our event publisher. When an event occurs (e.g., a new message is created), we use its tryEmitNext() method to send data into the stream.

This data then flows through the Flux to all connected GraphQL subscribers.

public class MessageService {

    private final Sinks.Many<Message> messageSink;

    public MessageService(Sinks.Many<Message> messageSink) {
        this.messageSink = messageSink;
    }

    public Message createMessage(String text, String channelId) {
        // ... save message to DB ...
        Message newMessage = new Message("1", text, channelId, "now");
        messageSink.tryEmitNext(newMessage); // Publish the new message
        return newMessage;
    }
}

Full Runnable Example Setup

Let's build a complete, runnable Spring Boot application. We'll define a Message record and a MessagePublisher component to manage our Sinks.Many.

record Message(String id, String text, String channelId, String timestamp) {}

import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Sinks;

@Component
public class MessagePublisher {
    private final Sinks.Many<Message> messageSink = 
        Sinks.many().multicast().onBackpressureBuffer();

    public Flux<Message> getMessageStream() {
        return messageSink.asFlux();
    }

    public void publishMessage(Message message) {
        messageSink.tryEmitNext(message);
    }
}

Main Application & Resolver

Now, we connect our MessagePublisher to the @SubscriptionMapping resolver. The Main class simulates sending a message after a delay.

Run this example to see the server-side publishing in action!

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.graphql.data.method.annotation.SubscriptionMapping;
import org.springframework.stereotype.Controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.time.Duration;

@SpringBootApplication
public class Main implements CommandLineRunner {

    @Autowired
    private MessagePublisher messagePublisher;

    public static void main(String[] args) {
        SpringApplication.run(Main.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        // Simulate sending a message after 2 seconds
        Mono.delay(Duration.ofSeconds(2))
            .subscribe(l -> {
                Message msg = new Message("2", "Hello from Spring!", "general", "now");
                messagePublisher.publishMessage(msg);
                System.out.println("Published: " + msg);
            });
    }
}

@Controller
class MessageSubscriptionController {
    private final MessagePublisher messagePublisher;

    public MessageSubscriptionController(MessagePublisher messagePublisher) {
        this.messagePublisher = messagePublisher;
    }

    @SubscriptionMapping
    public Flux<Message> messageAdded() {
        return messagePublisher.getMessageStream();
    }
}

record Message(String id, String text, String channelId, String timestamp) {}

Filtering Subscription Events

Clients often need updates specific to certain criteria. We can filter the Flux based on arguments passed to the subscription.

Here, clients only receive messages for a specified channelId.

import org.springframework.graphql.data.method.annotation.Argument;
// ... other imports ...

@Controller
class MessageSubscriptionController {
    private final MessagePublisher messagePublisher;

    public MessageSubscriptionController(MessagePublisher messagePublisher) {
        this.messagePublisher = messagePublisher;
    }

    @SubscriptionMapping
    public Flux<Message> messageAdded(@Argument String channelId) {
        return messagePublisher.getMessageStream()
            .filter(msg -> msg.channelId().equals(channelId));
    }
}

Decoupling Event Publishing

For better architecture, it's a good practice to decouple event publishing from your core business logic.

  • This keeps your services clean and focused.
  • It allows multiple independent subscribers to react to the same event without tight coupling.
  • Consider using Spring's ApplicationEventPublisher or a dedicated event bus for this.

Subscription Resolver Check

You've learned how to implement subscription resolvers in Spring Boot. Let's test your understanding!

Recap: Real-time Updates

You've successfully learned how to implement real-time updates using GraphQL subscriptions in Spring Boot!

  • Subscription resolvers return a Flux.
  • Sinks.Many is used to publish events into the Flux.
  • You can filter streams based on subscription arguments.
  • Decoupling publishing logic improves maintainability.

Perguntas Frequentes

A aula “Implementando Atualizações em Tempo Real” é grátis?

Sim — o texto completo de “Implementando Atualizações em Tempo Real” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de GraphQL APIs with Spring Boot, atualize para CoddyKit PRO. O curso de GraphQL APIs with Spring Boot inclui 4 aulas no total.

O que vou aprender em “Implementando Atualizações em Tempo Real”?

Desenvolva resolvedores de assinatura no Spring Boot para publicar eventos e enviar dados em tempo real aos clientes. Você pratica GraphQL APIs with Spring Boot com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar GraphQL APIs with Spring Boot?

Nenhuma experiência prévia é necessária. GraphQL APIs with Spring Boot no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 2 de 4.

Quanto tempo leva a aula “Implementando Atualizações em Tempo Real”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de GraphQL APIs with Spring Boot?

Sim. Cada aula de GraphQL APIs with Spring Boot inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Entendendo as Assinaturas GraphQL
  2. Implementando Atualizações em Tempo Real
  3. Integrando WebSockets ao Spring
  4. Filtragem e escalabilidade de assinaturas
← Voltar para GraphQL APIs with Spring Boot