Query content with Slice Machine + Content Relationship. Need help thinking through the best approach

Hello hello :wave:

I think I have reached a "slice machine + content relationship" edge case and need some help deciding the next steps.

But first, let me give you some context:

My team and I are migrating our blogs from WordPress to Prismic. We decided to use Prismic after having a great experience building the new version of getcircuit.com with the Slice Machine.

And for this new blog iteration, we decided to make it even more flexible through the power of slices + content relationship. The idea is to allow our editors to chose not only which Articles to show on a certain page, but also their position on the page.

For instance, we have a handful of slices like this:

...where, through fields like this:

our editors can control the position of a document.

And it works almost perfectly, as you can see here on this preview.

The problem

The problem is, whilst searching for the optimal way to query slices with relational content, I've stumbled upon a few different solutions, each with its own pros and cons. And I need help picking one.

GraphQL

I'll start with GraphQL and "go backwards" because that's what the preview actually uses. I've ended up trying it after failing with REST fetchLinks and graphQuery, but would be happy to go back to REST if it proves to be the best choice.

Example query

Pros

  • GraphiQL autocomplete is great and makes composing queries very easy.
  • I can query for relationships indefinitely with GraphQL, so I can do something like Page->Article->Category->Category Parent easily.
  • All the pros that come with using GraphQL (fragments, not having to make multiple round trips, etc).

Cons

  • Query parameters are not as flexible as REST (can't use predicates)
  • Only works with GET, so the query length is unexpectedly limited.
  • Slice variation queries with GraphQL are verbose, which makes the previous problem worse.
  • There is no way to ask for all slices of a page, which forces the user to explicitly ask for a slice and its variations before getting to the slice fields. Which makes the query limitation problem even worse.

Thoughts

I could try and minify the query but that wouldn't change the fact that it is a GET request and, at best, that would give us some time before becoming an issue again.

I also thought of querying for the list of slices and then running separate queries to get the data of each slice, thus avoiding the GET limitation. But that kind of defeats the purpose of using GraphQL in the first place.

REST + graphLinks

Example query

Before trying my luck with GraphQL I gave REST + graphLinks a try. The main motivator for trying graphLinks is because I have a Page->Article->Category in UIs like this:

So we need multi-level relationship support.

Pros

  • Always returns all slices of a page
  • When compared to GraphQL, Prismic REST offers more variation in terms of predicates and how we can query for content.

Cons

  • Poor client-side error handling, need to use API explorer for better errors.
  • Poor DX. Having to encode the query before running it with the API explorer is confusing.
  • Like with GraphQL, I'd need to make explicit which slices I'm in fact querying for. Which would make the request large and probably have the same 413 error.

Thoughts

While it allows multi-level relationship querying, graphLinks suffers from the same issues that GraphQL does when slices come into play.

REST + fetchLinks

We first got into Prismic through Slice Machine REST-based tutorials, so fetchLinks was our first try at adding linked content to queries we already were familiar with.

Pros

  • Super simple way to fetch 1 level deep relationships

Cons

  • Limited to 1 level deep relationships

Thoughts

While most of our pages require multi-level relationships, some don't, and fetchLinks offers a great, one-line solution for those cases.

REST + Multiple queries

Considering that GraphQL, graphLinks and fetchLinks each present their own limitations, I started discussing with my team if it makes sense to run an initial REST query to get the page slices and subsequent N queries to get all the relational content.

We could do that until the "slice machine + content relationship" combo is more mature and refactor when a more elegant solution arises.

Pros

  • A query always returns all slices of a page, without us needing to specify what we want.
  • Prismic API calls are unlimited and our project is an SSG Next app.

Cons

  • We need multiple round trips to Prismic to get a complete payload of a page, which would make our builds a bit slower and we'd have to implement some kind of local cache during build.

Thoughts

It is funny how putting a problem down in words makes you think about it deeper.

I started writing down this issue without leaning toward any of the available solutions, but after putting them down in words I started thinking that "REST + Multiple queries" might be the best course of action.

It is not elegant but it is predictable and easier to understand... I do, however, lack any information about Prismic backlog so, maybe I'm complaining about something that's about to change?

TL;DR;

There are multiple ways to query for a relationship field inside a slice, all of them have their pros and cons. None fits my use-case 100%.

I'm thinking of giving up on the idea of getting all the data in a single query and simply running one REST query for each id returned from each relationship field. I need help thinking this through. :thinking:

2 Likes

Hello @vitor1, thanks for sharing your use case in detail.

It is true that all the solutions you have listed come to the same place with their advantages and disadvantages.

It is actually a matter of preference. For example, some people choose GraphQL over REST only because they feel more comfortable using that queries format.

What I can say about REST is that, if you have to choose, it will always be better to use GraphQuery. In fact, this syntax was implemented as an upgrade to FetchLinks. Initially, we even called it FetchLinksV2.

At the moment we do not have a definite plan to modify the operation of the Content Relationship field. If this changes, we will make a public announcement on our progress page

I face up the same challenge. How do you end up solving this? What I am doing now is to use REST + Multiple queries. I first fetch all the slices and perform a second request to get all blogs with the ids. I then pass the blog data to a slice via context. I don't like this solution since the blog data will be available in all slices (via context) when I only need it in one place.

1 Like

I'm using multiple queries too, yeah. It is literally the only way to do it if you have a lot of slices and is already hitting that 413 error.

I'm using Next.js so at getStaticProps I make a first query to get the current page document, then recursively go through that response and run new queries whenever it finds a new relationship field.

1 Like