-
Notifications
You must be signed in to change notification settings - Fork 1.2k
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Plugin / middleware #172
Comments
@quietshu |
I'm not sure but I think this could happen on user-land? Create a |
Leaving I believe, in any typical frontend project that works with a RESTful API, you would expect to see either
If you guys agree, I can provide with a separate PR to make it a monorepo. |
I don't mean making function useSWRAxios(...args) {
// do something here to extend or reduce args
return useSWR(...newArgs)
} It's not hard to write a wrapper around a hook creating a new hook and support composition. |
@sergiodxa I believe you missed the related issues above that indicate a more complicated use case, especially for axios. I participate in discussions in other libs like react-async, react-query. |
@sergiodxa sorry for the noise, I believe I didn't provide enough arguments, so let me reply to you:
Look at the amount of work done in #145 Why not to combine efforts to seek the best practices, instead of everyone creating the same imperfect solutions over and over in their own repos? |
🤔 I think I get it, I'm still unsure about having plugins support in useSWR, maybe this repo could be a monorepo as you said and have two or more libs:
So if you want only SWR you And all of these extra packages could be custom hooks using Also those What do you think? @o-alexandrov @quietshu I'm mostly worry about adding a feature that could not be really necessary since hooks allow composability and specially it's probably not going to be used by ZEIT, I like that SWR comes from ZEIT internal usage since that guarantees me you are going to keep maintaining the lib and those features. |
@sergiodxa
@sergiodxa I believe you have a typo:
|
👀 |
What's going on with this issue?
Using SWR with HttpClient and Auth library become complicated. 😭 |
Thank you for sharing your use case here @matamatanot, it’s very helpful! I think instead of using a middleware, we can think about adding a new option
|
@shuding Thanks! A new option But, I think there is a better way. |
I see @matamatanot! While |
This is an interesting proposal. const plugin = next => (key, fn, config) => {
// preprocessing
const result = next(key, fn, config) // a chained middleware or useSWR
// postprocessing
return result
} The interface, which this PR proposes, has to override the fetcher implementation in many cases like logging. Personally, I feel it seems to be more clear to be able to add plugin implementations around the original The following is my experimentation with the interface. I think it depends on the use-case what the appropriate interface for the middleware system is, so this is just an idea. |
@koba04 Love your idea and demo, the support of postprocessing is so great! I think we can implement this.
The main goal is to build tooling around SWR, because data fetching is not just getting the data. For example in our particular use case we made a logger function that wraps the fetcher, so every request will be logged with its status. I believe that many people have built things like that repeatedly, and it will be great that SWR can provide a simple and lightweight middleware support so these things can be shared. |
Why would you need a complicated middleware feature for that though, if it's just a matter of making a wrapped fetcher function which does the logging? |
@Svish because that's not going to scale. The logger wrapper needs to be implemented differently for And also I believe this is not a "complicated feature", it's intuitive to me: import logger from 'swr-logger'
import { SWRConfig } from 'swr'
<SWRConfig value={{ use: logger }}>
<App/>
</SWRConfig> |
Proposed APItype SWRPluginNext = (key: Key, fn: Fetcher, config?: SWRConfiguration) => void
type SWRPlugin = (next: SWRPluginNext) => void Example const plugin = next => (key, fn, config) {
// ...
} Usages1. Add auth tokenconst userToken = resolveUserToken()
functuion fetcher(key, token) {
return fetch(key, {
headers: { 'X-User-Token': token }
})
}
const authFetcherPlugin = (next) => (key, fn, config) => {
const authedFetcher = (key) => fn(key, userToken)
return next(key, authedFetcher, config)
} This can help simplify the redudant array key use cases in useSWR when values in array are for fetcher only. 2. Error reportingconst errorReportPlugin = (next) => async (key, fn, config) => {
functuion fetcher(...args) {
let data, error
try {
data = fn(...args)
} catch (err) {
error = err
}
if (error) {
sentry.reportError(error)
throw error
}
return data
}
next(key, fetcher, config)
} I guess the solution could either be wrap swr with HOC or just wrap the fetcher to process data. |
This issue was moved to a discussion.
You can continue the conversation there. Go to discussion →
A plugin (or middleware) can extend the configuration, key, and fetcher function of SWR. With this feature we can make SWR lightweight and more customizable.
API
You can use multiple plugins too:
Or pass them to the context:
Implementation Details
swrAxios
should be a function, which accepts all the params passed to the SWR hook, and return the extended ones:That way, middleware can be chained, and you will also be able to use custom configs too (because they'll be passed to the handlers).
Ideas
fetch
polyfill, orisomorphic-fetch
, etc.)...
Related Feature Requests
The text was updated successfully, but these errors were encountered: