Just clarifying that I did read all of Apollo Client Best Practices (and gotchas): Video Walkthrough before deciding to post this. This was a topic that I brought up originally in Discord and am moving over here for a cleaner and clearer conversation. For those brave enough to traverse the Discord history, here’s the original post: Discord
My question was:
Best practice question - if I want to add dynamic content to a layout, the solution is to make a new Cell and use that to fetch in the space I want to collect the data, right? Along those lines, if I’m having multiple cells on a single page - is Apollo then batching the request from the client to avoid crazy waterfalls or should I be doing a super query at the page root level and then adapting additional cells to query but it’ll leverage the cache because I did it as a super query? If going the super query route, should I use GQL fragments and how does Redwood support them?
To break this down, I really have a couple of branching questions around best practice of implementation.
Question 1: Adding dynamic content to a layout - are Cells the best practice?
Let’s say in my Routes.tsx
, I have the following:
<Router>
<Set wrap={EventLayout}>
<Route path="/events/{eventId}/sessions" page={EventSessions} name="eventSessions" />
</Set>
</Router>
My EventLayout
will look like this:
const EventLayout = ({ children }) => {
return (
<>
<nav>
<EventTitleCell />
<UserProfileDropdownCell />
</nav>
{children}
</>
);
};
Ideally, EventTitleCell
pulls the event record’s title to display in my nav and the UserProfileDropdownCell
will be like most websites where it shows your login info and gives you the menu to logout or explore your settings. My question is: is this considered the best practice in Redwood for dealing with dynamic data in layouts?
Question 2: Batching of GraphQL Queries
Having every Cell query the API is pretty inefficient if there’s overlap in data. For instance, in my above example, I could have a route at /events/{eventId}
using the EventLayout that acts more like a dashboard that has the event info in the nav but also on the page with some other data that may also include the event’s info. All the sudden I have a lot of redundant data requests that I’d like to avoid. Is the default Redwood Apollo config set to leverage client batching?
If not, what is considered to be the best practice here? David’s recommendation in Discord was to leverage useQuery
at the Layout layer. However, I don’t want to make a Layout per Page to achieve this. Ideally though, the Cells making up my pages could export query fragments and then the parent page/container could batch them as a single Query operation. The Cells could still perform the Query leveraging the Fragment and read from the cache but the parent making the big query would avoid the waterfalls I’m concerned about.
As an example, I could write my cell GQL like this:
// EventCell
export const QUERY = gql`
query FindEventById($id: String!) {
event: event(id: $id) {
id
...EventCellFragment
}
}
`;
export const FRAGMENT = gql`
fragment EventCellFragment on Event {
id
name
description
startAt
endAt
}
`
Then the page could have a parent query that runs on load that pulls all fragments from all children cells. The Cell is still performant reading from cache and the parent page could avoid the unnecessary waterfalls. Of course, if a fragment isn’t provided, then the current behavior would persist and you could still run waterfalls.
Note: it’s late and I’m little tired so I may have forgotten some key points that I’m carrying forward from Discord. Please call me out if something in this is confusing or doesn’t make sense - I’d love to update to clarify.