Что такое восклицательный знак в graphql?

В файле схемы, который у меня есть, я заметил, что после некоторых типов есть восклицательные знаки, например

# Information on an account relationship
type AccountEdge {
  cursor: String!
  node: Account!
}

Что это значит? Я не могу найти ничего об этом в документации или через googling 😅

Ответ 2

Из спецификации:

По умолчанию все типы в GraphQL обнуляются; нулевое значение является действительным ответом для всех вышеперечисленных типов. Чтобы объявить тип, который запрещает нуль, можно использовать ненулевой тип GraphQL. Этот тип переносит базовый тип, и этот тип действует идентично этому упакованному типу, за исключением того, что null не является допустимым ответом для типа переноса. Завершающий восклицательный знак используется для обозначения поля, в котором используется ненулевой тип, например: name: String !.

Другими словами, типы в GraphQL по умолчанию обнуляются. Восклицательный знак после типа специально определяет этот тип как ненулевой.

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

Выход

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

Например, дана схема типа:

type Query {
  user: User
}

type User {
  id: ID!
}

Здесь поле id является нулевым. Помечая поле как ненулевое, мы фактически гарантируем, что никогда не вернем нуль для этого поля. Если сервер возвращает null, это означает, что что-то пошло не так, и мы хотим выдать ошибку проверки.

вход

Когда ненулевое значение применяется к типу входных данных, таких как аргумент, поле входного объекта или переменная, это делает этот ввод обязательным. Например:

type Query {
  getUser(id: ID!, status: Status): User
}

Здесь аргумент id является нулевым. Если мы запрашиваем поле getUser, нам всегда нужно будет предоставить для него аргумент id. С другой стороны, поскольку аргумент status имеет значение null, он необязательный и может быть опущен. Это относится и к переменным:

query MyQuery ($foo: ID!) {
  getUser(id: $foo)
}

Поскольку переменная $foo равна нулю, при отправке запроса она не может быть опущена и ее значение не может быть равно null.

Особое примечание по типам переменных

Поскольку в нашем примере поле id является ненулевым ID (то есть ID!), Любая передаваемая нами переменная также должна быть ненулевым ID. Если бы наша переменная $foo представляла собой обнуляемый ID, мы не могли бы передать его в аргумент id. Однако обратное неверно. Если аргумент обнуляем, вы можете передать его ненулевой переменной.

Другими словами:

+----------+----------+--------+
| Argument | Variable | Valid? |
+----------+----------+--------+
| String   | String   |   ✅   |
| String   | String!  |   ✅   |
| String!  | String   |   ❌   |
| String!  | String!  |   ✅   |
+----------+----------+--------+