A couple of patterns to fetch content using GraphQL in headless application

In this blog post, I picked up a couple of headless component code blocks I worked-on and have discussed the pros and cons of each approach. This post is more of an hindsight by presenting the facts with the idea of continuous improvement thus opening doors for betterment.

One of the main differences when it comes to headless applications compared with Sitecore MVC world is, the limit in fetching content from back-end. In other words, headless world is dependent on GraphQL queries while the earlier Sitecore MVC versions were LINQ-based. As a result, the records fetched by GraphQL have a default limit of 10. This could be a pain-point or surprise for developers coming from the back-end world since they are used to a select * mindset. In other words, they had better control over the no. of records to fetch while GraphQL or headless world doesn't entertain such an approach. Needless to say, this limit by headless applications is meant to improve performance or drive better headless design patterns when it comes to data/content fetch and front-end rendering. In those lines, in this post, I'm about to present a couple of patterns related to content fetch with GraphQL. As someone from the back-end API world, I felt GraphQL is too picky and it is important to understand that aspect in order to use it effectively. To explain this better, one of the common issues you face while executing queries with GraphQL is this annoying error - Query is too complex. While there are so many different responses for this issue, one of the best responses is in this post by Ghodrat Ashournia that states how to reduce query complexity. It is important to understand and rewrite your queries based on the notes in the above blog post to overcome the "query is too complex to execute" error and in turn to fetch content as a bunch with GraphQL. Although fetching records in bulk is not a viable approach in the headless world, it is good to know about it and hold it in the back pocket as an interim solution or fit it into scenarios where you can/want.

Here are a few points I've shared to get a better understanding of when I used either of the approaches:

1. Bulk Fetching:

- Apply filtering conditions on fetched records in the front-end like, Employee Search List

- Aware of max records in the back-end 

- Will need Vercel redeployment since GraphQL query with max count is part of front-end code

GraphQL Query example:


Note that the usage of template name and jsonvalue are what reduced the query complexity in the above case.

Code flow:

Although there could be multiple ways to accomplish the same requirement via NextJS (SSR/SSG etc.) and it is all dependent on the practical requirement, I'm depicting one approach that worked for my requirement. Note that this simplified version of the code-flow doesn't provide the specific first-time/next-time request/response details but just outlines the code-flow once the browser has downloaded the JS and other asset artifacts from Vercel after the react environment is setup in the browser:


Most importantly, useEffect does the job of interacting with Experience Edge by sending the graphql query and receiving the json result. Finally, filtering, paging logic happen completely in the client-side. 

Sample page:




SearchFilter.tsx:
/////

2. Cursor-based Paging:

- Records grow on a daily-basis like, News Article List

- Items in page dependent on cursor size

- Simple fetch and display, no filtering needed in front-end

- Better scalability

- No Vercel deployment required, one-time setup

The best part about this approach is, the end-user has better control over the pages since the page number is passed as part of query string. In other words, it is search-engine-friendly compared with the earlier approach.

GraphQL Query example:

Code flow:

The user indirectly invokes the react router to fetch the specific page. Call gets transferred to Experience Edge by passing graphql query with page number and page size to fetch the items in that page. The json response result is styled and then rendered in the user browser. The main difference between this particular code and the earlier one is, there is no specification of record count in the GQL query. So, this component can relatively stand-alone. Obviously, there is scope to better the hard-coded page size into an environment variable of its own.



Sample page:


ArticleListing.tsx:









Comments