oscartbeaumont / rspc

A framework for building typesafe web backends in Rust
https://rspc.dev
MIT License
1.1k stars 50 forks source link

Feat/add fetch and prefetch to solid #288

Closed johann-crabnebula closed 1 week ago

johann-crabnebula commented 1 week ago

This PR adds functions to fetch and prefetch via the rspc-client in the solid-package.

The problem we had at CrabNebula Cloud was that we could not fetch or prefetch via the @rspc-solid package. At least not without creating a new observer every time. This PR opens a potential option.

We agreed to go for the same useUtils style that @solid-mediakit/trpc is using.

const utils = directory.useUtils();

utils
  .fetchQuery(["orgs.list"])
  .then(orgs => {
      return queryUtils.prefetchQuery(["invitations.listByOrg", orgs]);
  });

At the moment only prefetchQuery and fetchQuery are implemented.

Brendonovich commented 1 week ago

Another approach for supporting prefetching would be something like useUtils from trpc (which I'd prefer). I assume you're prefetching in solid router's load functions? This approach would allow you to do something like this (assuming the router is wrapped with rspc's provider)

function load() {
  rspc.useUtils().prefetchQuery(["some.key"])
}

And your example could be

const rspcUtils = rspc.useUtils();
rspcUtils
  .fetchQuery(["your-query-key", { param: test }])
  .then((result) =>
    rspcUtils.prefetchQuery(["your-query-key-2", { param: request1Result }]),
  );

The utils object would basically be a typesafe wrapper around all of the QueryClient's functions. Whether you consume them inside a createResource or an event handler or a load function would be up to you.

johann-crabnebula commented 1 week ago

I see... That was also the direction @oscartbeaumont was pointing in I think. Totally didn't get it the first time around.

Will have a look at the implementation from trpc.

johann-crabnebula commented 1 week ago

Made another attempt looks more like this now:

const queryUtils = directory.createQueryUtils();

queryUtils
  .fetchQuery(["orgs.list"])
  .then(orgs => {
      const currentOrgId = orgs?.find(org => org.slug === params.orgSlug)?.id;
      if (!currentOrgId) throw new Error("Could not find org");
      console.log("prefetch org");
      return queryUtils.prefetchQuery(["invitations.listByOrg", currentOrgId]);
  });
johann-crabnebula commented 1 week ago

Updated the naming of the export to useUtils and updated the description.