I think I have reached a "slice machine + content relationship" edge case and need some help deciding the next steps.
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 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.
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.
- GraphiQL autocomplete is great and makes composing queries very easy.
- I can query for relationships indefinitely with GraphQL, so I can do something like
- All the pros that come with using GraphQL (fragments, not having to make multiple round trips, etc).
- 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.
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.
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.
- 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.
- 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.
While it allows multi-level relationship querying, graphLinks suffers from the same issues that GraphQL does when slices come into play.
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.
- Super simple way to fetch 1 level deep relationships
- Limited to 1 level deep relationships
While most of our pages require multi-level relationships, some don't, and fetchLinks offers a great, one-line solution for those cases.
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.
- 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.
- 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.
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?
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.