question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[RFC] Subscription mode for SWR

See original GitHub issue

Define the Problem

currently useSWR and useSWRInfinite are more designed for endpoints or data sources that can directly access and patch proactively. The data flow is like below

useSWR <=== write and read ====> data source

But for some cases SWR doesn’t have enough solid ability to interact with data sources such as observable data (states returned from an observable stream), subscribable data (data been sent from a remote websocket endpoint).

then the fetcher of SWR will lose meaning since they’re not really accessible initiavely from user end. we can surly do a subscribe or observe call to attach on the source. however we cannot know the state of a certain time.

besides fetcher, the mutate, trigger and revalidate APIs are also kind f disabled due to the passive mode. I want to find a new way to think of the communication path.

Solution

propose to bring a new hook API useSWRSubscription to SWR to fit in the subscribable situation. unlike the basic useSWR hook, it won’t return the manipulation APIs of useSWR.

API

function useSWRSubscription(key, subscribeFn: (onData, onError) => Disposable): {data?, error?};

Usage

// like the useSWRInfinite, we put it into an extra file
// or in the future we could make it import useSWRSubscription from 'swr/subscription'
import {useSWRSubscription} from 'swr'

const {data, error} = useSWRSubscription('wss://my.app/api/chat-messages', subscribeWs)

function subscribeWs(key, {onData, onError}) {
   const ws = new WebSocket(key)
   ws.onmessage = (event) => { 
      onData(event.data)
   }
   ws.onerror = (error) => {
      onError(event.data)   
   }
   return () => ws.close()
}

then in this case, if the key changed, SWR is able to close and re-subscribe to the source for new key; the uncertain thing is the returned error might not always be valid since some obseravle won’t throw error when the connection get closed;

Other Possible Solutions

make revalidate and returned trigger with no effect. but mutate is still able to patch states to that key

Pros & Cons

Pros

  • support realtime data
  • adaptive to any observable data source, user can also do customization upon it
  • simple returned values to let user to leverage, no mind load on the meaning of revalidate/mutate/trigger

Cons

  • if there’s any new API can access the current data, like geo API is subscribable but getting current position of geo is also doable. might need to have some workaround for that…
  • more APIs into SWR, might bring confusion to new users to choose API

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:7
  • Comments:9 (7 by maintainers)

github_iconTop GitHub Comments

2reactions
sergiodxacommented, Nov 19, 2020

Just come to mention that my PR (#457) come from a different use-case than the idea of the RFC.

The useSWRObservable hook is to get data from an observable source without when you don’t have a non-observable source. This is useful when your source of data is only WebSockets or something real-time so you can’t use a fetcher, it makes total sense here.

My proposal to add a subscribe in the config comes from a different idea where you have an API you can fetch with a fetcher but you want to start a subscription to an observable-source to receive updates without using long-polling.

Imagine this flow, in your fetcher you do a GET /api/resource/1 to get the resource with ID 1, then your subscribe to /ws//resource/1 in a WS server, this way you get an initial up-to-date data for your resource and thank to the subscription if something change in the server you don’t need to wait for SWR to revalidate it, the API will let you know, and the reason to pass mutate is that sometimes this WS servers can return the new data, sometimes they return a delta of what changed so you will need to call mutate to apply the update, and sometimes they return that something changed and you will need to trigger a revalidation against the HTTP API.


So, I think we should support both, useSWRObservable and the subscribe option in useSWR.

2reactions
shudingcommented, Oct 29, 2020

Thank you for writing this amazing RFC!

ws.onmessage = (event) => { return event.data };

This doesn’t solve the data problem right? Like how do I notify SWR that I got the data (or error).

const {data, error} =

I think we can probably also return a connecting or loading value, which indicates the initial connection state (before the first value arrives).

or in the future we could make it import useSWRObservable from ‘swr/observable’

I’m 👍 on doing it.

Read more comments on GitHub >

github_iconTop Results From Across the Web

[RFC] Subscription mode for SWR · Discussion #1052 - GitHub
I want to find a new way to think of the communication path. Solution. propose to bring a new hook API useSWRSubscription to...
Read more >
RFC 4601 - Sparse Mode (PIM-SM)
Abstract This document specifies Protocol Independent Multicast - Sparse Mode (PIM-SM). PIM-SM is a multicast routing protocol that can use the underlying ...
Read more >
Shu on Twitter: "New APIs in SWR 1.2.0 (beta)! • Mutate with ...
New APIs in SWR 1.2.0 (beta)! • Mutate with optimistic value • Populate cache after ... [RFC] Subscription mode for SWR · Discussion...
Read more >
Caching clash: SWR vs. TanStack Query for React
The abbreviation “SWR” stands for State While Re-validate, a generic caching principle from HTTP RFC 5861. React SWR was first released in 2019 ......
Read more >
How to Fetch and Update Data From Ethereum With React ...
SWR first returns the data from cache (stale), then sends the fetch request ... Applications can subscribe and listen to these events through...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found