Почему регистрация и я всегда в типах мутации и запроса?

Я изучаю GraphQL, и в КАЖДОМ примере, который я видел, вызовы signup/login и me относятся к типам mutation и query. Это почему? Пример:

type Query {
  me: User
}

type Mutation {
  login(email: String!, password: String!): String
}

Разве это не должно быть в типе User? Поскольку это связано с пользователем?

Я извиняюсь, если это вопрос, основанный на мнении, и я закрою вопрос, если это так.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
0
470
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Этот вопрос основан на дизайне схемы GraphQL. Дизайн на 100% основан на мнении. Но позвольте мне попробовать ответить на ваш вопрос.

В ответе на мутацию login клиент должен получить токен авторизации или аналогичный. Этот token будет отправляться как HTTP-заголовок при каждом запросе на авторизацию. Очевидно, что этот token не является частью User сущности. В сложном приложении вы можете разработать ответ на мутацию следующим образом:

{
  user: ...
  token: ...
}

Но для демо-приложения нужен только токен (строка) в качестве ответа на мутацию login.

Ответ принят как подходящий

Из спец.:

There are three types of operations that GraphQL models:

  • query – a read‐only fetch.

  • mutation – a write followed by a fetch.

  • subscription – a long‐lived request that fetches data in response to source events.

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

schema {
  query: Query
}

Здесь Query относится к типу с именем Query. По соглашению эти три типа названы Query, Mutation и Subscription, но их можно назвать как угодно, это не имеет большого значения. Однако они должны быть объектными типами и должны включать по крайней мере одно поле.

Эти типы операций служат «корнем» операции GraphQL и фактически являются точками входа в ваш граф данных. Никакие другие типы не отображаются на корневом уровне, даже если они существуют в вашей схеме.

Поле me или viewer часто отображается в типе Query, чтобы пользователи могли получить текущего пользователя, вошедшего в систему. Предполагая, что у нас уже есть определенный тип User, если мы добавим поле me к нашему типу Query и установим для этого поля тип User, мы позволим потребителям нашей конечной точки написать запрос, например:

query {
  me {
    # some set of User fields like id, firstName, etc.
  }
}

Если вместо этого мы поместим поле me в тип User, а) у нас не обязательно будет способ запросить поле, поскольку оно не будет в корне, и б) мы будем отображать поле me везде, где мы возвращаем User ( например, поле friends, которое возвращает список Users), что не имеет особого смысла.

Та же логика применима к мутациям вроде login — мы хотим, чтобы они были в корне нашей операции, поэтому мы помещаем их внутрь типа Mutation. С другой стороны, должен ли login быть мутацией или запросом, субъективен и зависит от вашего конкретного варианта использования.

Небольшое отступление от мутаций:

Если вы привыкли работать с REST, часто можно увидеть операции с префиксом источников данных, с которыми они работают, например:

POST /articles/{id}/bookmark

И мы можем быть склонны применять аналогичную структуру с нашими мутациями, что приводит к таким запросам, как:

mutation {
  article {
    bookmark
  }
}

Однако это совершенно не нужно, фактически нарушает соглашение и усложняет реализацию. Вместо этого достаточно сделать:

mutation {
  bookmarkArticle
}

Подробнее об этом можно узнать здесь.

Получается два отдельных вопроса.

Первый ответ здесь: если вы делаете запрос GraphQL, вам нужен какой-то способ заставить объекты начать запрашивать. Нет понятия "статические методы", как в Java или других объектно-ориентированных языках; этот набор начальных запросов должен быть корневого типа Query. Вы можете себе представить

type Query {
  "The currently logged-in user."
  me: User!

  "Find a user by their email address."
  user(email: String!): User
}

Вы можете запросить другие поля объекта User, как только он у вас появится, но сначала вам нужен какой-то способ получить его.

query WhatsMyEmail {
  me { email }
}

Во-вторых, все операции по изменению данных являются полями верхнего уровня типа Mutation. В основном это соглашение — ничто фактически не мешает вам делать все, что вы хотите в своих функциях преобразователя, — но у него есть несколько ключевых последствий. Достаточно просто запросить каждое поле объекта и сгенерировать такой запрос из схемы:

fragment AllUserFields on User {
  id, name, email, delete
}
query WhoAmI {
  me { ...AllUserFields } # oops I deleted myself
}

У вас также есть гарантия, что мутации верхнего уровня выполняются по порядку, но все остальное в GraphQL может выполняться в любом порядке. Если ваша схема позволяет это, email может быть как старым, так и новым адресом электронной почты, например:

query ChangeMyEmail {
  me {
    changeEmail(email: "[email protected]")
    email  # is allowed to evaluate first and return [email protected]
  }
}

Такие вещи, как «логин», которые на самом деле являются просто «действиями», не привязанными к какому-либо конкретному объекту, имеют больше смысла просто привязываться к Mutation, а не к какому-либо более конкретному типу. (Если «логин» был свойством User, то каким, и как его найти, не входя в систему?)

Другие вопросы по теме