Observable
Observable<T> is the type that augments the promise returned by a client .get() call. On top of being an awaitable promise, an observable lets you subscribe to future values for the same cache entry, so long-lived views can react when the underlying data changes.
export type Observable<T> = { readonly queryKey?: string; subscribe(callback: (value: Promise<T>) => void): () => void;};A .get() therefore returns Promise<T> & Observable<T>:
const result = client.users.get();
// use it as a promiseconst users = await result;
// or subscribe to updatesconst unsubscribe = result.subscribe((next) => { next.then((users) => render(users));});queryKey
Section titled “queryKey”The fetch client supplies the request URL as queryKey, identifying the cached query. Compare it by value; different URLs (including query parameters) have different keys.
useQuery uses this identity to keep resolved data visible during background refreshes. It is optional for custom observables: without it, the observable promise itself identifies the query.
subscribe(callback)
Section titled “subscribe(callback)”callback— invoked with aPromise<T>each time the cache entry for this URL is invalidated and re-fetched. The callback receives a promise (not a resolved value) because the fresh data may still be loading; awaiting it also lets you observe errors.- Returns — an unsubscribe function. Call it to stop receiving updates.
Subscribing pushes the current value immediately. The callback then fires again when something invalidates the URL: a tag-matching mutation, an explicit .revalidate() call, or a scheduled TTL-based revalidation.
const result = client.todos.get();
const unsubscribe = result.subscribe((next) => { next .then((todos) => setTodos(todos)) .catch((err) => console.error(err));});
// later, when the view unmounts:unsubscribe();Unlike earlier versions of this client, subscribing does not keep the cache entry alive by itself — entries are only removed by an error, an explicit invalidation, or TTL expiry, regardless of whether anyone is subscribed.
Relationship to @toapi/react
Section titled “Relationship to @toapi/react”@toapi/react wraps this subscribe/unsubscribe protocol in React hooks so components re-render automatically on cache changes. Observable is the underlying primitive; use it directly when integrating with other frameworks or state stores.