Apollo GraphQL: Resolver не вызывается в подполе мутации - PullRequest
0 голосов
/ 18 декабря 2018

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

. Вы можете запустить и изменить этот код на https://codesandbox.io/s/1z8kjy8m93

Сервер

const { ApolloServer, gql } = require("apollo-server");

const typeDefs = gql`
  type Query {
    hello(msg: String): String
  }

  type Mutation {
    someMutation(someArg: String): MutationResponse
  }

  type MutationResponse {
    query: Query
    status: String
  }
`;

const resolvers = {
  Query: {
    hello: (root, args, context) => {
      console.log("hello: args = ", args);
      return `${args.msg}, world !`;
    }
  },
  Mutation: {
    someMutation: (root, args, context) => {
      console.log("someMutation: args = ", args);
      return { status: `Mute Mute: ${args.someArg}` };
    }
  }
};

const server = new ApolloServer({
  typeDefs,
  resolvers
});

server.listen().then(({ url }) => {
  console.log(`? Server ready at ${url}`);
});

Мутация

mutation mutateMe($mutationArg: String = "YoloMute !", $helloMsg: String = "Yolhello") {
  someMutation(someArg: $mutationArg) {
    status
    query {
      hello(msg: $helloMsg)
    }
  }
}

Ответ

{
  "data": {
    "someMutation": {
      "status": "Mute Mute: YoloMute !",
      "query": null
    }
  }
}

ДонНе понятно, почему не вызывается решатель hello, а поле query равно null.

Поле status должным образом заполнено решателем someMutation, но как queryполе не разрешено там, я ожидал бы, что GraphQL вызовет существующий преобразователь для этого поля, который существует и должен вызываться для типа Query.

Я нашел другие способы, которые технически работают, но не удовлетворяют:

1 Ответ

0 голосов
/ 18 декабря 2018

Эта проблема на самом деле не относится только к типу Query, а скорее касается того, как вы настроили свои преобразователи.

Поле состояния должным образом заполнено преобразователем someMutation,но так как поле запроса там не разрешено, я ожидал бы, что GraphQL вызовет существующий преобразователь для этого поля, который существует и должен вызываться для типа запроса.

Не существует преобразователя для всего Query тип или любой другой тип.Разрешители существуют только для отдельных полей определенного типа.Если для поля определитель не определен, GraphQL по умолчанию будет искать свойство родительского объекта с тем же именем, что и у поля, и будет возвращать значение этого свойства.

Давайте пройдемся по вашемудокумент.Поле корневого уровня:

someMutation(someArg: $mutationArg)

Родительским значением является корневое значение для всех мутаций корневого уровня.Если вы не используете пользовательское корневое значение, это обычно будет пустой объект.Если вы не определили определитель для поля someMutation типа Mutation, GraphQL будет искать свойство с именем someMutation в вашем корневом значении и вернет его (т. Е. Неопределенное, которое будет приведено к нулю вответ).Но у нас do есть определитель, и он возвращает:

{
  status: `Mute Mute: ${args.someArg}`,
}

Теперь давайте разрешим поле status.Наш родительский объект - это результат, возвращаемый распознавателем родительского поля.В этом случае объект выше.У нас нет распознавателя для status на MutationResponse, поэтому GraphQL ищет свойство status на родительском объекте - он находит его и использует его.status имеет скалярный тип, поэтому любое значение, возвращаемое распознавателем, будет приведено к соответствующему скалярному значению.

Как насчет поля query?Опять же, у нас нет резольвера для поля query на MutationResponse.Однако у нас также нет свойства с именем query для родительского объекта.Таким образом, все, что может сделать GraphQL, - это вернуть ноль для этого поля.

Несмотря на то, что тип возвращаемого значения для query равен ObjectType, поскольку он разрешается в null, любые средства распознавания для полей в этом ObjectType будутне быть уволенным.Возвращение null означает, что объект не существует, поэтому нам не нужно беспокоиться о разрешении каких-либо полей в нем.Представьте, что поле вернуло объект User.Если бы он возвратил нуль, не было бы необходимости разрешать имя пользователя, например.

Итак ... как нам обойти это?Есть два способа:

Либо добавить свойство для query к объекту, возвращаемому распознавателем someMutation, например:

{
  status: `Mute Mute: ${args.someArg}`,
  query: {},
}

Или добавить преобразователь для поля:

MutationResponse: {
  query: () => {},
},

В любом случае поле query будет преобразовано в ненулевое значение (в данном случае просто пустой объект).Поскольку разрешенное значение не равно null, а тип возвращаемого значения - ObjectType (в данном случае Query), сейчас , резольверы для полей этого типа будут вызваны, и hello будет разрешаться какожидается.

...