🎉 Выпущен Gato GraphQL v0.7 с поддержкой mutations и nested mutations!
Выпущена версия 0.7 Gato GraphQL с поддержкой mutations и nested mutations! 🎉

Вот обзор новых возможностей.
1. Mutations! 🚀
GraphQL mutations позволяют изменять данные (то есть выполнять побочные эффекты) через запрос.
Mutations были главной недостающей частью Gato GraphQL. Теперь, когда они добавлены, я могу утверждать, что этот GraphQL-сервер практически функционально завершён (не хватает только subscriptions, и я уже думаю над тем, как их добавить).

Рассмотрим пример добавления комментария. Но сначала нам нужно выполнить ещё одну mutation для входа в систему, чтобы вы могли добавлять комментарии. Нажмите кнопку «Run» в клиенте GraphiQL ниже, чтобы выполнить поле mutation loginUser с заранее созданным тестовым пользователем:
mutation LogUserIn {
loginUser(
by: { credentials: { usernameOrEmail: "test", password: "pass" } }
) {
id
name
}
}Теперь добавим несколько комментариев. Нажмите кнопку Run ниже, чтобы добавить комментарий к записи, выполнив поле mutation addCommentToCustomPost (вы также можете изменить текст комментария):
mutation AddComment {
addCommentToCustomPost(
input: { customPostID: 1459, comment: "Adding a comment: bla bla bla" }
) {
id
content
date
}
}В этом первом релизе плагин поставляется со следующими mutations:
✅ createPost
✅ updatePost
✅ setFeaturedImageforCustomPost
✅ removeFeaturedImageforCustomPost
✅ addCommentToCustomPost
✅ replyComment
✅ loginUser
✅ logoutUser
2. Nested Mutations! 🚀🚀
Nested mutations — это возможность выполнять mutations на типе, отличном от root type в GraphQL.
Они были запрошены для спецификации GraphQL, но ещё не утверждены (и возможно, никогда не будут), поэтому Gato GraphQL добавляет поддержку этой возможности как opt-in функцию через модуль Nested Mutations.
Таким образом, плагин поддерживает 2 варианта поведения:
- Стандартное поведение GraphQL (то есть добавление полей mutation к root type) — по умолчанию
- Nested mutations — как opt-in
Например, запрос из примера выше также можно выполнить следующим запросом, в котором мы сначала получаем запись через Root.post, а затем добавляем к ней комментарий через Post.addComment:
mutation AddComment {
post(by: { id: 1459 }) {
addComment(
input: {
comment: "Notice how field `addCommentToCustomPost` under the `Root` type is renamed as `addComment` under the `Post` type? The schema got neater!"
}
) {
id
content
date
}
}
}Mutations также могут изменять данные на основе результата другой mutation. В запросе ниже мы сначала получаем запись через Root.post, затем выполняем mutation Post.addComment на ней и получаем созданный объект комментария, и наконец выполняем mutation Comment.reply на нём:
mutation AddCommentAndResponse {
post(by: { id: 1459 }) {
id
title
addComment(input: { comment: "Isn't this awesome?" }) {
id
date
content
reply(input: { comment: "I think so!" }) {
id
date
content
}
}
}
}Это действительно полезно! 😍 (Альтернативный способ получить то же самое поведение в одном запросе — через директиву @export... Я сравню оба варианта в одном из следующих постов блога).
В этом первом релизе плагин поставляется со следующими mutations:
✅ CustomPost.update
✅ CustomPost.setFeaturedImage
✅ CustomPost.removeFeaturedImage
✅ CustomPost.addComment
✅ Comment.reply
Стандартный или nested? Или оба?
Возможно, у вас есть GraphQL API, который использует ваше собственное приложение, и который также публично доступен для ваших клиентов. Вы можете захотеть включить nested mutations, но только для вашего приложения, а не для клиентов, поскольку это нестандартная функция.
Хорошая новость: вы можете это сделать.
Я добавил раздел «Mutation Scheme» в Schema Configuration, который используется для настройки схемы для Custom Endpoints и Persisted Queries:

Таким образом, вы можете отключить nested mutations везде, но включить их только для конкретного custom endpoint, который будет использовать только ваше приложение. 💪
Удаление избыточных полей из root type
При использовании nested mutations поля mutation могут быть добавлены в схему дважды:
- один раз под root type
- один раз под конкретным типом
Например, эти поля можно считать «дубликатами» друг друга:
Root.updatePostPost.update
Gato GraphQL позволяет сохранить оба или удалить те, что находятся в root type и являются избыточными.
Следующие 3 схемы:
- Стандартное поведение:
использует типыQueryRootдля обработки queries иMutationRootдля обработки queries - Nested mutations с сохранением дублирующихся полей mutation:
единый типRootобрабатывает queries и mutations, и избыточные поля mutation в этом типе сохраняются - Nested mutations с удалением избыточных полей mutation из root type:
то же самое, но с удалением всех избыточных полей mutation из типаRoot
✱ Кстати1, все 3 схемы используют один и тот же endpoint, но с изменением URL-параметра ?mutation_scheme на значения standard, nested и lean_nested. Это возможно, потому что GraphQL-сервер следует подходу code-first. 🤟
✱ Кстати2, эти параметры можно выбрать в разделе «Mutation Scheme» в Schema configuration (показан выше), поэтому вы также можете решить, какое поведение применять для отдельных custom endpoints и persisted queries. 👏
Теперь пора начать подготовку к v0.8! 🙏