В простых случаях часто можно использовать преобразователь по умолчанию. для получения необходимых данных. Однако, чтобы реализовать что-то вроде фильтрации данных в кеше или манипулирования ими (как вы делаете с мутациями), вам нужно написать свой собственный преобразователь. Чтобы выполнить то, что вы пытаетесь сделать, вы можете сделать что-то вроде этого:
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.
Это означает, что мы можем, например, вернуть объект, представляющий одну задачу, и нам не нужно определять преобразователь для его полей 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
(единственное число), не имеет соответствующего свойства в корне (кэш). Вам нужно написать преобразователь, чтобы он возвращал данные. Точно так же, если вы хотите манипулировать данными перед их возвратом в запросе (с аргументами или без них), вам необходимо включить преобразователь.
person
Daniel Rearden
schedule
29.05.2018