Использование Apollo's writeFragment для обновления вложенного списка - PullRequest
1 голос
/ 18 марта 2020

Я работаю над приложением, в котором корабль можно настроить с помощью рулей и других вещей. Структура базы данных является своего рода вложенной, и до сих пор я держал свои запросы GraphQL в соответствии с базой данных.

Это означает: я мог бы получить судно, используя какой-то запрос (ShipId, shipId), но вместо этого Я использую вложенный запрос:

query {
    project(id:1) {
        id
        title
        ship(id:1) {
            id
            name
            rudders {
                id
                position
            }
        }
    }
}

Такая структура, конечно, приводит к множеству вложенных массивов. Например, если я только что добавил новый руль, мне нужно было бы получить его с помощью cache.readQuery, который дает мне объект проекта, а не список рулей. Чтобы добавить руль в кеш, я получу длинную строку с вложенными, деструктурированными объектами, что затруднит чтение кода.

Поэтому я подумал об использовании фрагментов GraphQL. Что касается inte rnet, я вижу, что они часто используются для предотвращения необходимости перепечатывать несколько полей на обширных объектах (что лично мне тоже очень полезно!). Однако не так много примеров, когда фрагмент используется для массива.

Фрагменты для массивов могут сохранить всю деструктуризацию объекта при добавлении некоторых данных в массив, который вложен в некоторый кэшированный запрос. Используя Apollo readFragment и writeFragment, мне удалось получить что-то работающее.

Фрагмент:

export const FRAGMENT_RUDDER_ARRAY = gql`
    fragment rudderArray on ShipObject {
        rudders {
            id
            position
        }
    }
`

Используется в запросе основного корабля:

query {
    project(id: ...) {
        id
        title
        ship(id: ...) {
            id
            name
            ...rudderArray
        }
    }
}
${RUDDER_FRAGMENT_ARRAY}

Используя это, Я могу написать гораздо более понятную функцию update () для обновления кэша Аполлона после мутации. Смотрите ниже:

const [ createRudder ] = useMutation(CREATE_RUDDER_MUTATION, {
    onError: (error) => { console.log(JSON.stringify(error))},
    update(cache, {data: {createRudder}}) {
        const {rudders} = cache.readFragment({
            id: `ShipObject:${shipId}`,
            fragment: FRAGMENT_RUDDER_ARRAY,
            fragmentName: 'rudderArray'
        });

        cache.writeFragment({
            id: `ShipObject:${shipId}`,
            fragment: FRAGMENT_RUDDER_ARRAY,
            fragmentName: 'rudderArray',
            data: {rudders: rudders.concat(createRudder.rudder)}
        });
    }
});

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

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

...