I'm using RedwoodJS.

My front-end (what they call the "web" "side") has (among other files) a HomePage.ts and MainCell.ts, and then the Success function in MainCell calls a 3rd party API.

Everything is working.

However, I now want to start caching the results from the 3rd party API.

I've created a database table and a back-end "service" called cachedQueries.ts (using Prisma), which has:

export async function getFromCacheOrFresh(key: string, getFresh: Function, expiresInSec: number): Promise<any> {
  const nowMoment = dayjs.utc();
  const nowStr = nowMoment.format(dbTimeFormatUtc);
  const cached = await getCachedQuery({ key, expiresAtCutoff: nowStr });
  console.log('getFromCacheOrFresh cached', cached);
  if (cached) {
    const cachedValueParsed = JSON.parse(cached.value);
    console.log('cachedValueParsed', cachedValueParsed);
    return cachedValueParsed;
  } else {
    const fresh = await getFresh();
    saveToCache(key, JSON.stringify(fresh), expiresInSec);
    return fresh;
  }
}

I have proven that this cachedQueries.ts service works and properly saves to and retrieves from the DB. I.e. for any 3rd-party APIs that can be called from the back-end (instead of from the front-end), the flow all works well.

Now my challenge is to enable it to cache front-end 3rd-party API queries too.

How I can call my getFromCacheOrFresh function from the Success function of the MainCell in the front-end?

I must be confused about Apollo, GraphQL, RedwoodJS, Prisma, etc relate to each other.

P.S. Client-side caching will not suffice. I really need the 3rd-party API results to be saved in the DB on my server.

1

There are 1 best solutions below

1
On

I eventually figured it out.

I created a new cell called GeoCell, and I'm returning an empty string for each function of GeoCell (Success, Loading, Empty, and Failure).

That feels weird but works.

What was unintuitive to me was the idea that I was required to use a JSX component (since Apollo would never let me query or mutate GraphQL outside of a JSX component), but I didn’t want the cell component to actually display anything… because all that it needs to do in its Success is call a helper function that affects elements aleady created by a different cell (i.e. addMarkerAndInfoWindow affects the div of the existing Google Map but doesn’t display anything where the GeoCell was actually located).

As https://stackoverflow.com/a/65373314/470749 mentions, there's a related discussion on the Redwood Community Forum: Thinking about patterns for services, GraphQL, Apollo, cells, etc.