GraphQL-API-er med Spring Boot · leksjon

Implementering av sanntidsoppdateringer

Utvikle abonnementsresolvere i Spring Boot for å publisere hendelser og sende aktive data til klienter.

Leksjon 2 av 411 trinn

Implementering av sanntidsoppdateringer er en gratis leksjon i GraphQL-API-er med Spring Boot på CoddyKit. Dette er leksjon 2 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i GraphQL-API-er med Spring Boot, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i GraphQL-API-er med Spring Boot inneholder totalt 4 leksjoner.

Subscription-resolvere forklart

Subscriptions leverer oppdateringer i sanntid. I motsetning til queries, som returnerer data én gang, returnerer subscription-resolvere en datastrøm som kontinuerlig sender oppdateringer til klientene.

Vi skal lære å implementere disse strømmene i en Spring Boot GraphQL-applikasjon.

Ta i bruk Reactor Flux

Spring GraphQL bruker Project Reactors Flux til å håndtere subscriptions. En Flux representerer en asynkron, ikke-blokkerende strøm med 0 til N elementer.

  • Den egner seg godt for kontinuerlig levering av data.
  • Du kan sende ut flere verdier over tid.

Skjema for sanntidsoppdateringer

Først definerer vi subscriptionen vår i GraphQL Schema Definition Language (SDL). Dette eksempelet viser en subscription for nye meldinger:

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

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

Opprette en subscription-resolver

I Spring Boot er en subscription-resolver en metode merket med @SubscriptionMapping. Den må returnere en Flux av den ønskede typen.

Vi bruker en Sinks.Many til å administrere og publisere hendelser til denne strømmen.

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();
    }
}

Publisere hendelser med Sinks.Many

Instansen av Sinks.Many fungerer som hendelsesutgiveren vår. Når en hendelse oppstår, for eksempel når en ny melding opprettes, bruker vi metoden tryEmitNext() til å sende data inn i strømmen.

Disse dataene flyter deretter gjennom Flux til alle tilkoblede GraphQL-abonnenter.

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;
    }
}

Fullstendig oppsett som kan kjøres

La oss bygge en komplett Spring Boot-applikasjon som kan kjøres. Vi definerer en Message-record og en MessagePublisher-komponent som administrerer 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);
    }
}

Hovedapplikasjon og resolver

Nå kobler vi MessagePublisher til resolveren med @SubscriptionMapping. Klassen Main simulerer sending av en melding etter en forsinkelse.

Kjør dette eksempelet for å se publisering på serversiden i praksis!

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) {}

Filtrere subscription-hendelser

Klienter trenger ofte oppdateringer som er begrenset til bestemte kriterier. Vi kan filtrere Flux basert på argumenter som sendes til subscriptionen.

Her mottar klientene bare meldinger for en angitt 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));
    }
}

Frikoble hendelsespublisering

For å oppnå en bedre arkitektur er det god praksis å frikoble publisering av hendelser fra kjernelogikken i applikasjonen.

  • Dette holder tjenestene ryddige og fokuserte.
  • Det gjør det mulig for flere uavhengige abonnenter å reagere på samme hendelse uten tett kobling.
  • Vurder å bruke Springs ApplicationEventPublisher eller en dedikert event-buss til dette.

Kontroll av subscription-resolver

Du har lært hvordan du implementerer subscription-resolvere i Spring Boot. La oss teste forståelsen din!

Oppsummering: Sanntidsoppdateringer

Du har lært hvordan du implementerer sanntidsoppdateringer ved hjelp av GraphQL subscriptions i Spring Boot!

  • Subscription-resolvere returnerer en Flux.
  • Sinks.Many brukes til å publisere hendelser til Flux.
  • Du kan filtrere strømmer basert på argumentene til subscriptionen.
  • Frikobling av publiseringslogikken gjør vedlikehold enklere.
Gratis å komme i gang

Lær deg GraphQL-API-er med Spring Boot med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
12
Leksjoner
48

Ofte stilte spørsmål

Er leksjonen «Implementering av sanntidsoppdateringer» gratis?

Ja – hele teksten i «Implementering av sanntidsoppdateringer» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av GraphQL-API-er med Spring Boot-kurset, kan du oppgradere til CoddyKit PRO. Kurset i GraphQL-API-er med Spring Boot inneholder totalt 4 leksjoner.

Hva lærer jeg i «Implementering av sanntidsoppdateringer»?

Utvikle abonnementsresolvere i Spring Boot for å publisere hendelser og sende aktive data til klienter. Du øver på GraphQL-API-er med Spring Boot med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med GraphQL-API-er med Spring Boot?

Ingen tidligere erfaring er nødvendig. GraphQL-API-er med Spring Boot på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.

Hvor lang tid tar leksjonen «Implementering av sanntidsoppdateringer»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne GraphQL-API-er med Spring Boot-leksjonen?

Ja. Alle GraphQL-API-er med Spring Boot-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Forstå GraphQL-abonnementer
  2. Implementering av sanntidsoppdateringer
  3. Integrering av WebSockets med Spring
  4. Filtrering og skalering av subscriptions
← Tilbake til GraphQL-API-er med Spring Boot