Implementera uppdateringar i realtid
Utveckla prenumerationsresolvers i Spring Boot för att publicera händelser och skicka data i realtid till klienter.
Implementera uppdateringar i realtid är en gratis lektion i GraphQL-API:er med Spring Boot på CoddyKit. Detta är lektion 2 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för GraphQL-API:er med Spring Boot, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i GraphQL-API:er med Spring Boot innehåller totalt 4 lektioner.
Prenumerationsresolverare förklarade
Prenumerationer levererar uppdateringar i realtid. Till skillnad från frågor, som returnerar data en gång, returnerar prenumerationsresolverare en dataström som kontinuerligt skickar uppdateringar till klienterna.
Vi ska lära oss att implementera dessa strömmar i en Spring Boot GraphQL-applikation.
Använda Reactor Flux
Spring GraphQL använder Project Reactors Flux för att hantera prenumerationer. En Flux representerar en asynkron, icke-blockande ström med 0 till N objekt.
- Den passar utmärkt för kontinuerlig dataleverans.
- Du kan skicka ut flera värden över tid.
Schema för realtidsuppdateringar
Först definierar vi vår prenumeration i GraphQL Schema Definition Language (SDL). Det här exemplet visar en prenumeration för nya meddelanden:
type Subscription {
messageAdded(channelId: ID!): Message
}
type Message {
id: ID!
text: String!
channelId: ID!
timestamp: String!
}Skapa en prenumerationsresolverare
I Spring Boot är en prenumerationsresolverare en metod som annoteras med @SubscriptionMapping. Den måste returnera en Flux av den önskade typen.
Vi använder en Sinks.Many för att hantera och publicera händelser i denna ström.
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();
}
}Publicera händelser med Sinks.Many
Instansen Sinks.Many fungerar som vår händelsepublicerare. När en händelse inträffar, till exempel när ett nytt meddelande skapas, använder vi dess metod tryEmitNext() för att skicka data till strömmen.
Dessa data flödar sedan genom Flux till alla anslutna GraphQL-prenumeranter.
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;
}
}Komplett körbart exempel
Nu bygger vi en komplett, körbar Spring Boot-applikation. Vi definierar en Message-post och en MessagePublisher-komponent som hanterar vår 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);
}
}Huvudapplikation och resolverare
Nu kopplar vi vår MessagePublisher till resolveraren med @SubscriptionMapping. Klassen Main simulerar att ett meddelande skickas efter en fördröjning.
Kör exemplet för att se publicering på serversidan i praktiken!
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) {}Filtrera prenumerationshändelser
Klienter behöver ofta uppdateringar som är specifika för vissa kriterier. Vi kan filtrera Flux baserat på argument som skickas till prenumerationen.
Här tar klienterna endast emot meddelanden för ett angivet 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));
}
}Frikoppla händelsepublicering
För en bättre arkitektur är det en god praxis att frikoppla händelsepubliceringen från den centrala affärslogiken.
- Det håller tjänsterna rena och fokuserade.
- Det gör det möjligt för flera oberoende prenumeranter att reagera på samma händelse utan stark koppling.
- Överväg att använda Spring:s
ApplicationEventPublishereller en dedikerad händelsebuss.
Kontroll av prenumerationsresolverare
Du har lärt dig att implementera prenumerationsresolverare i Spring Boot. Nu testar vi din förståelse!
Sammanfattning: realtidsuppdateringar
Du har lärt dig att implementera realtidsuppdateringar med GraphQL-prenumerationer i Spring Boot!
- Prenumerationsresolverare returnerar en
Flux. Sinks.Manyanvänds för att publicera händelser iFlux.- Du kan filtrera strömmar baserat på prenumerationsargument.
- Frikoppling av publiceringslogiken förbättrar underhållbarheten.
Lär dig GraphQL-API:er med Spring Boot med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 12
- Lektioner
- 48
Vanliga frågor
Är lektionen ”Implementera uppdateringar i realtid” gratis?
Ja – hela texten till ”Implementera uppdateringar i realtid” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i GraphQL-API:er med Spring Boot, kan Ni uppgradera till CoddyKit PRO. Kursen i GraphQL-API:er med Spring Boot innehåller totalt 4 lektioner.
Vad lär jag mig i ”Implementera uppdateringar i realtid”?
Utveckla prenumerationsresolvers i Spring Boot för att publicera händelser och skicka data i realtid till klienter. Ni övar på GraphQL-API:er med Spring Boot med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig GraphQL-API:er med Spring Boot?
Du behöver inga förkunskaper. Utbildningen i GraphQL-API:er med Spring Boot på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 2 av 4.
Hur lång tid tar lektionen ”Implementera uppdateringar i realtid”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här GraphQL-API:er med Spring Boot-lektionen?
Ja. Varje GraphQL-API:er med Spring Boot-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Förstå GraphQL-prenumerationer
- Implementera uppdateringar i realtid
- Integrera WebSockets med Spring
- Filtrera och skala subscriptions