Для простых случаев использования часто можно полагаться на распознаватель по умолчанию для получения необходимых данных.Однако, чтобы реализовать что-то вроде фильтрации данных в кеше или манипулирования ими (как вы делаете с мутациями), вам нужно написать свой собственный преобразователь.Чтобы выполнить то, что вы пытаетесь сделать, вы можете сделать что-то вроде этого:
export const resolvers = {
Query: {
todos: (obj, args, ctx) => {
const query = gql`
query GetTodos {
todos @client {
id
text
}
}
`
const { todos } = ctx.cache.readQuery({ query })
return todos.filter(todo => todo.id === args.id)
},
},
Mutation: {},
}
РЕДАКТИРОВАТЬ: Каждый тип, который мы определяем, имеет набор полей.Когда мы возвращаем определенный тип (или список типов), каждое поле этого типа будет использовать распознаватель по умолчанию, чтобы попытаться разрешить свое собственное значение (при условии, что это поле было запрошено).Способ разрешения по умолчанию работает просто - он смотрит на значение родительского (или «корневого») объекта и, если находит свойство, соответствующее имени поля, возвращает значение этого свойства.Если свойство не найдено (или не может быть приведено к какому-либо Scalar или Type, ожидаемому полем), оно возвращает null.
Это означает, что мы можем, например, вернуть объект, представляющий одну Todo, инам не нужно определять преобразователь для его полей id
или text
, если объект имеет свойства id
и text
.Если посмотреть на это с другой стороны, если бы мы хотели создать произвольное поле в Todo
с именем textWithFoo
, мы могли бы оставить значения по умолчанию в кэше без изменений и создать преобразователь типа
(obj, args, ctx) => obj.text + ' and FOO!'
. В этом случаераспознаватель по умолчанию не принесет нам пользы, потому что объекты, хранящиеся в кэше, не имеют свойства textWithFoo
, поэтому мы пишем свой собственный преобразователь.
Важно помнить, что запрос типа todos
- это тоже просто поле (в данном случае это поле типа запроса).Он ведет себя почти так же, как любое другое поле (включая поведение распознавателя по умолчанию).Однако с apollo-link-state
структура данных, которую вы определяете в defaults
, становится родительским или «корневым» значением для ваших запросов.
В вашем примере кода defaults
включает одно свойство (todos
).Поскольку это свойство корневого объекта, мы можем получить его с помощью запроса todos
и получить данные даже без распознавателя.Средство распознавания по умолчанию для поля todos
будет искать в корневом объекте (в данном случае ваш кеш), видеть свойство с именем todos
и возвращать его.
С другой стороны, запрос типа todo
(единственное) не имеет соответствующего свойства в корне (кеш).Вам нужно написать распознаватель, чтобы он возвращал данные.Точно так же, если вы хотите манипулировать данными перед их возвратом в запрос (с аргументами или без них), вам необходимо включить распознаватель.