plasmicapp / plasmic

Visual builder for React. Build apps, websites, and content. Integrate with your codebase.
https://www.plasmic.app
MIT License
4.69k stars 377 forks source link

[fetcher] useSWRMutation, add state, extended configuration in Studio #102

Closed georg-malahov closed 6 months ago

georg-malahov commented 7 months ago

Motivation:

Current backend integrations sometimes have unpredictable load times, generally much longer than fetching directly from the endpoint server without going through Plasmic servers. As a workaround, we can use a browser fetch API. However, it has several problems, making it difficult to use in many cases.

Problems with Browser Fetch API:

  1. It is currently impossible to configure the underlying SWR directly for revalidation on focus, on mount, on reconnect, etc.
  2. Managing the cache is challenging. There is no clear way to access the default query key and use it for mutation. Or to revalidate on page revisit when data was mutated on another page, as all fetched data is now immutable by design.
  3. Manually calling mutation requests, for example, for form submission, is very difficult and requires workarounds like conditional rendering.
  4. The only way to get data and handle fetch states is by using slots.
  5. It is not possible to access error data, such as request status code and additional information from the server response.

Suggested Solutions:

  1. Make certain SWR configuration options available from the Studio.
  2. Use mutable SWR requests that can be fully configured from the Studio.
  3. Make use of the useSWRMutation hook available from the second major version of the SWR library.
  4. Provide extended error data like status codes and info.
  5. Add a readable component state that can be accessed from other components on the page and allows easy access to fetch states, data, errors, and some methods like mutate and trigger.
  6. Add onError, onSuccess, and other eventHandlers, allowing convenient component integrations besides using slots.

Known Caveats:

The SWR Library from the 2nd major version mainly disallows using suspense on the server side, breaking the current Plasmic SSR prepass mechanism. See this GitHub issue for more details.

Therefore, we continue using the existing useMutablePlasmicQueryData for fetching data, which is still based on the prior SWR version and supports react-ssr-prepass. For manual mutation requests, the 2nd version of SWR is used.

All this makes it harder to provide and use the correct SWR configuration, leading to potential inconsistencies with caching, especially when using custom cache providers, suspense, fallback, and fallbackData properties.

image

image

image

vercel[bot] commented 7 months ago

The latest updates on your projects. Learn more about Vercel for Git ↗︎

1 Ignored Deployment | Name | Status | Preview | Comments | Updated (UTC) | | :--- | :----- | :------ | :------- | :------ | | **react-email-demo** | ⬜️ Ignored ([Inspect](https://vercel.com/plasmic/react-email-demo/AdNDb6M5rQuvj57woWDF7ZVRumji)) | | | Nov 28, 2023 7:11pm |
IcaroG commented 6 months ago

Hey @georg-malahov , thanks for the contribution. Sadly, I don't think we can merge these changes. Firstly, as you've said, we are not ready for SWR 2 yet, as it would break our prepass logic. Also, this highly increases the complexity of the builtin fetcher. I think if someone wants to have all these features themselves it's fine to only let them achieve it only through code components.

georg-malahov commented 6 months ago

@IcaroG No, it doesn't break current prepass logic. As prepass make sense only for queries, not mutations, queries still use existing useMutablePlasmicQueryData, so nothing breaks. The only thing is that there would be two different versions on SWR used for queries and mutations. The prepass isn't broken. How would it increase the complexity of the builtin fetcher, as builtin fetcher wasn't changed?

chungwu commented 6 months ago

@georg-malahov thanks for your PR! From what I understand, you'd like to make data fetches from the client / browser (without going through the Plasmic proxy), but the only way to do so is via the "HTTP REST API Fetcher" code component (the one in @plasmicpkgs/plasmic-query), and that fetcher does not support a lot of things you'd like from swr (revalidation, mutation, etc).

Our preference here, though, is to continue evolving our data integrations framework, by adding support for client-only data sources in the near future. We think it's a better experience for working with data than the bespoke fetcher components.

georg-malahov commented 6 months ago

@chungwu Thanks for your answer! Yes, you are right, I wanted to extend the possibilities of the "HTTP REST API Fetcher" without breaking the current functionality. And I managed to replace and migrate from the current component to the updated one quite seamlessly.

Could you share a link to what is on the roadmap for evolving the data integrations framework, and especially regarding the client-only data sources?

I also initially tried using integrations, but I faced difficulty in understanding how to update the endpoints from development to production, or how to switch the entire pre-configured integrations when transitioning between environments. Is this a known limitation? Do you have any suggestions on how to manage this?

chungwu commented 6 months ago

Could you share a link to what is on the roadmap for evolving the data integrations framework, and especially regarding the client-only data sources?

We don't have one handy... I imagine this is something we'll get better at as we start doing more work in the open!

I also initially tried using integrations, but I faced difficulty in understanding how to update the endpoints from development to production, or how to switch the entire pre-configured integrations when transitioning between environments. Is this a known limitation? Do you have any suggestions on how to manage this?

You're right! This is definitely a current limitation without a good workaround 😓