Содержимое GraphQL, деструктурирующее фрагменты в массиве

Возникла проблема с фрагментами в запросе графа для сайта Гэтсби, над которым я работаю, который использует Contentful в качестве CMS:

Рассмотрим следующий запрос:

export const query = graphql`
    query ComposablePageQuery($slug: String!) {
        contentfulPage(slug: { eq: $slug }) {
            __typename
            contentful_id
            slug
            sections {
                __typename
                contentful_id
                ... on ContentfulModelA {
                    fieldA
                    fieldB
                }
                ... on ContentfulModelB {
                    fieldC
                    fieldD
                }
            }
        }
    }
`;

Теперь переменная разделов представляет собой массив, который может принимать разные ссылки на модели. В моем случае у меня есть две модели, ModelA и ModelB, с тривиальными полями ради этого вопроса.

Проблема в том, что если хотя бы один экземпляр каждого из них не включен в массив разделов на конкретной странице, я получаю следующую ошибку:

There was an error in your GraphQL query:

Fragment cannot be spread here as objects of type "ContentfulModelA" can never be of type "ContentfulModelB".

Если в массиве разделов присутствуют экземпляры обеих моделей, проблем нет.

Итак, как это можно решить? Я хочу, чтобы запрос обрабатывал случай, когда ModelA OR ModelB может присутствовать в списке, но без гарантии. Это кажется разумным запросом, учитывая, что в веб-дизайне можно предвидеть, что конкретная страница может быть богата одной конкретной моделью и полностью лишена другой, а другая страница наоборот, а другая страница может сочетать в себе обе модели.

Я также пробовал явно объявлять фрагменты и заменять использование встроенных фрагментов, как показано выше, но та же ошибка сохраняется.

--

Примечание. Одним из обходных путей является создание экземпляров фиктивных записей для каждой модели и включение их в массив. модели будут изменены, чтобы включить логическую переменную, чтобы продемонстрировать, что ее на самом деле не следует использовать, а затем эти фиктивные экземпляры отфильтровываются во внешнем интерфейсе. Однако это придется делать на каждой странице, и этот подход похож на попытку заправить иголку кувалдой. Конечно, есть лучший обходной путь. Что происходит, когда в массив можно добавить десятки различных моделей?

--

🤔 А знаете ли вы, что...
React позволяет создавать пользовательские интерфейсы для веб-приложений.


52
1

Ответ:

Решено

Я думаю, вы захотите определить тип Section как союзContentfulModelA и ContentfulModelB

union Section = ContentfulModelA | ContentfulModelB