Skip to content

Reactive endpoints

Reactive endpoints turn repeated or long-running HTTP requests into a stream of entities, so you get notified of changes instead of reading a resource once.

Packages

For .NET, add the TypedRest.Reactive NuGet package. For Java/Kotlin, add the typedrest-reactive Maven artifact. In TypeScript, reactive endpoints are part of the main typedrest package.

Streams

.NET and Java/Kotlin provide streams as ReactiveX observables via GetObservable()/getObservable(). TypeScript provides them as async iterables via stream().

Nothing is sent until you subscribe to the observable or start iterating.

Stopping a stream

Dispose the subscription. This cancels the request or the wait between polls.

using var subscription = events.GetObservable()
    .Subscribe(x => Console.WriteLine(x.Type));

// ...

subscription.Dispose();

Dispose the subscription:

Disposable subscription = events.getObservable()
    .subscribe(x -> System.out.println(x.getType()));

// ...

subscription.dispose();

Dispose the subscription:

val subscription = events.getObservable()
    .subscribe { println(it.type) }

// ...

subscription.dispose()

break out of the loop. To stop a stream from somewhere else, pass an AbortSignal to stream(). For a streaming collection, the signal is the second argument, after the start index:

const controller = new AbortController();
setTimeout(() => controller.abort(), 60_000);

for await (const x of events.stream(controller.signal)) {
    console.log(x.type);
}

Aborting ends the loop normally rather than throwing. A polling endpoint is the exception while a request is in flight: aborting it then throws the AbortError from fetch.

Choosing an endpoint

Polling Streaming collection SSE Streaming
Delivers changed states of one resource new elements of a collection events entities
Transport repeated GET repeated GET with Range one long-lived GET one long-lived GET
Server requirements none range requests SSE output line-separated output
Delay up to one polling interval up to one polling interval immediate immediate
Resuming not needed by start index by Last-Event-ID not supported
Good for job status, slow-changing state logs, feeds, message histories notifications, live dashboards simple feeds you don't control

As a rule of thumb: use polling if you cannot change the server, a streaming collection if the data is a list that only grows and clients need to catch up on what they missed, and SSE if updates must arrive immediately.

Long-lived connections need some care in your infrastructure: proxies and load balancers may close idle connections or buffer responses. The SSE endpoint reconnects for you, but disable response buffering on the server side for streamed responses such as text/event-stream.

The Live updates tutorial uses polling, a streaming collection and SSE for different parts of one API.