Динамическое создание вызова мутации Apollo GraphQL в Angular - PullRequest
1 голос
/ 03 апреля 2020

У меня есть рабочий вызов мутации в моем приложении Angular для изменения некоторых полей объекта с помощью Apollo GraphQL. Часть вызова мутации включает в себя некоторые возвращаемые данные, которые Apollo свяжет с некоторым объектом, уже находящимся в его кеше, и обновит его новым возвращенным значением.

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

Мне удалось динамически сгенерировать документ мутации, который включает только изменяемые поля, и я передаю его в apollo.mutate({mutation: newMutation, ...}), который возвращает наблюдаемое. Мутация срабатывает только после подписки на наблюдаемое. Я проверил, что компонент, использующий эту подписку, отписывается и уничтожается до вызова новой мутации.

Проблема в том, что Apollo кэширует документ мутации и отправляет первую мутацию (только с поля мутировали в первый раз) для всех звонков. Я подтвердил это, проверив вкладку «Сеть» моего веб-браузера.

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

Кто-нибудь знает, что я делаю неправильно?

1 Ответ

0 голосов
/ 06 апреля 2020

Хорошо, я понял это. Клиент Apollo добавляет документы мутации в свой ROOT_MUTATION. Я обнаружил, что использование функций writeData / writeQuery клиента Apollo позволяет только добавлять / изменять ROOT_QUERY.

Изначально я пытался динамически добавлять поля в мой GraphQL AST . Код выглядел примерно так:

import gql from 'graphql-tag';
...
const myMutation = gql`
  mutation myMutation($id: ID!, ...) {
    mutateFields(id: $id, ...) {
      id  # You need to return at least one field or it will complain
      # Add mutated fields to return here
    }
  }
`;

# dynamically call the following lines based on fields to be added
myMutation.definitions[0].selectionSet.selections[0].selectionSet.selections = [
  {...}  # Added my own fields and their subfields here
];

Проблема заключалась в том, что он работал в первый раз, поэтому я знал, что корректно изменял GraphQL AST, однако последующие вызовы (с возвращаемыми новыми полями) были созданы правильно но Аполлон высылал первую мутацию с тем же именем (я проверил вкладку «Сеть» моего браузера для проверки).

РЕШЕНИЕ:

Не изменяйте GraphQL Вместо этого измените его как строковый литерал, аналогичный комментарию Алирезы Харири к этому сообщению: GraphQL dynamici c построение запроса .

Пример кода:

const mainMutation = `
   mutation myMutation($id: ID!, ...) {
    mutateFields(id: $id, ...) {
      id  # You need to return at least one field or it will complain
      # REPLACE_THIS_WITH_FIELDS
    }
  }
`;

const mutationWithFields = mainMutation.replace(
  `# REPLACE_THIS_WITH_FIELDS`,
  "myField { mySubfield1 mySubfield2 }"
);

const finalMutation = gql`${mutationWithFields}`;
this.apollo.mutate({
  mutation: finalMutation,
  variables: {
    id: myId,
    ...
  }
});
...