Методы мутации должны быть на верхнем уровне? - PullRequest
0 голосов
/ 31 января 2019

Все документы и учебные пособия обычно показывают простые примеры мутаций, которые выглядят следующим образом:

extend type Mutation {
  edit(postId: String): String
}

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

type PostMutation {
  edit(postId: String): String
}

extend type Mutation {
  post: PostMutation
}

Кажется, что это правильная схема (она компилируется, и я вижу ее отражение в сгенерированном графе-i-qlдокументы).Но я не могу найти способ заставить преобразователи работать с этой схемой.

Это поддерживаемый случай для GraphQL?

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Абсолютно не согласен с Дэниелом!

Это удивительный подход, который помогает внешним пользователям быстро понять, какие операции имеют тот или иной ресурс / модель.И не перечисляйте более длинные списки мутаций.

Вызов нескольких мутаций в одном запросе является обычным антипаттерном.Для таких случаев лучше создать одну сложную мутацию.

Но даже если вам нужно выполнить такую ​​операцию с несколькими мутациями, вы можете использовать псевдонимы:

await graphql({
  schema,
  source: `
  mutation {
    op1: article { like(id: 1) }
    op2: article { like(id: 2) }
    op3: article { unlike(id: 3) }
    op4: article { like(id: 4) }
  }
`,
});

expect(serialResults).toEqual([
  'like 1 executed with timeout 100ms',
  'like 2 executed with timeout 100ms',
  'unlike 3 executed with timeout 5ms',
  'like 4 executed with timeout 100ms',
]);

См. Следующий тестовый пример: https://github.com/nodkz/conf-talks/blob/master/articles/graphql/schema-design/tests/mutations-test.js

Такие методы, как / в отличие, асинхронны с таймаутами и работают последовательно

0 голосов
/ 31 января 2019

Это возможно , но обычно это не очень хорошая идея, потому что:

Это нарушает соглашение. По соглашению, мутации всегда находятся в корне.Чтобы различать выполнение одного и того же действия над разными типами, вы называете свои мутации, например, editPost и editComment, а не просто edit.

Наличие мутаций в корне делаетконцептуально. Независимо от того, что вы делаете (лайк, проверка электронной почты, отправка заказа и т. д.), не требуется, чтобы GraphQL разрешал дополнительные поля перед выполнением действия.Это непохоже, когда вы на самом деле запрашиваете данные.Например, чтобы получить комментарии к сообщению, нам может потребоваться разрешить поле user, затем поле posts и, наконец, поле comments для каждого сообщения.На каждом «уровне» содержимое поля зависит от значения, к которому разрешено родительское поле.Обычно это не относится к мутациям.

Под капотом мутации разрешаются последовательно .Это противоречит нормальному разрешению поля, которое происходит параллельно.Это означает, что, например, firstName и lastName типа User разрешаются одновременно.Однако, если ваш тип операции mutation, все корневые поля будут обрабатываться по одному за раз.Таким образом, в таком запросе:

mutation SomeOperationName {
  createUser
  editUser
  deleteUser
}

Каждая мутация будет происходить по одному в том порядке, в котором они появляются в документе.Тем не менее, это работает только для корня и только тогда, когда операция имеет значение mutation, поэтому эти три поля будут разрешаться параллельно:

mutation SomeOperationName {
  user {
    create
    edit
    delete
  }
}

Если вы все еще хотите это сделать, несмотря на вышеизложенное, этоэто то, как вы делаете это при использовании makeExecutableSchema, то есть то, что Apollo использует под капотом:

const resolvers = {
  Mutation: {
    post: () => ({}), // return an empty object,
  },
  PostMutation: {
    edit: () => editPost(),
  },
  // Other types here
}

Ваша схема определила PostMutation как тип объекта, поэтому GraphQL ожидает, что это поле вернет объект,Если вы опустите преобразователь для post, он вернет ноль, что означает, что ни один из преобразователей для возвращаемого типа (PostMutation) не будет запущен.Это также означает, что мы также можем написать:

mutation {
  post
}

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

...