Как отделить логи c при обновлении кеша Apollo, который используется как глобальное хранилище? - PullRequest
1 голос
/ 28 января 2020

Использование кеша Apollo в качестве глобального хранилища - для удаленных и локальных данных, очень удобно.

Однако, хотя я никогда не использовал Redux, я думаю, что самое важное в нем - это реализация Flux: управляемая событиями архитектура во внешнем интерфейсе, которая разделяет логи c и обеспечивает разделение задач.

Я не знаю, как реализовать это с помощью Apollo. Do c говорит:

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

Добавление функции update в одну часть приложения, которая обрабатывает все обновления кэша; Обновление запросов и / или фрагментов для всех других частей приложения - это именно то, чего мы хотим избежать в Flux / Event-based архитектуре.

Чтобы проиллюстрировать это, позвольте мне дать один простой пример. Здесь мы имеем (как минимум 3 связанных компонента)

1. InboxCount Компонент, который показывает количество элементов Inbox в SideNav

query getInboxCount {
    inbox {
        id
        count
    }
}

2. Элементы списка входящих Компонент, отображающий элементы на странице входящих

query getInbox {
    inbox {
        id
        items {
            ...ItemPreview
            ...ItemDetail
        }
    }
}

Оба эти компонента читают данные из этих запросов GQL из автоматически сгенерированных хуков ie. const { data, loading } = useGetInboxItemsQuery()

3. AddItem Компонент, который создает новый элемент. Поскольку создает новую сущность, мне нужно вручную обновить cache. Поэтому я вынужден написать

(псевдокод)

    const [addItem, { loading }] = useCreateItemMutation({
        update(cache, { data }) {
            const cachedData = cache.readQuery<GetInboxItemsQuery>({
                query: GetInboxItemsDocument,
            })

            if (cachedData?.inbox) {

                // 1. Update items list GetInboxItemsQuery
                const newItems = cachedData.inbox.items.concat(data.items)
                cache.writeQuery({
                    query: GetInboxItemsDocument,
                    data: {
                        inbox: {
                            id: 'me',
                            __typename: 'Inbox',
                            items: newItems,
                        },
                    },
                })

               // 2. Update another query wrapped into another reusable method, here
                setInboxCount(cache, newItems.length)
            }
        },
    })

Здесь мой AddItem компонент должен быть осведомлен о других моих других объявленных запросах / фрагментах в моем приложении ? Более того, поскольку оно довольно многословно, сложность очень быстро увеличивается в методе update. Особенно, когда нужно обновить несколько списков / запросов, например здесь

У кого-нибудь есть рекомендации по внедрению более независимых компонентов? Я ошибаюсь, как я создал свои запросы?

1 Ответ

1 голос
/ 28 января 2020

Печальная правда о update заключается в том, что он меняет простоту на производительность. По-настоящему «тупой» клиент будет только получать данные с сервера и обрабатывать их, а не манипулировать ими. Указывая Apollo, как изменить наш кэш после мутации, мы неизбежно дублируем бизнес-логику c, которая уже существует на нашем сервере. Единственный способ избежать этого - либо:

  • сделать так, чтобы мутация возвращала больший участок графика. Например, если пользователь создает сообщение, а не возвращает созданное сообщение, возвращает полный объект пользователя, включая все сообщения пользователя.
  • Повторное получение соответствующих запросов.

Конечно, зачастую ни один из этих подходов не является особенно желательным, и вместо этого мы выбираем внедрение бизнес-логики c в наши клиентские приложения.

Разделение этой бизнес-логики c может быть столь же простым, как хранение функций обновления в отдельном файл и импортировать их по мере необходимости. Таким образом, по крайней мере, вы можете протестировать логи обновления c отдельно. Вы также можете предпочесть более элегантное решение, такое как использование ссылки. apollo-link-watched-mutation является хорошим примером ссылки, которая позволяет вам отделить update logi c от ваших компонентов. Это также решает проблему необходимости отслеживать переменные запроса для выполнения этих обновлений.

...