Из спецификации:
Тип объекта GraphQL (ObjectTypeDefinition) ... не подходит для повторного использования [в качестве ввода], поскольку типы объектов могут содержать поля, которые определяют аргументы или содержат ссылки на интерфейсы и объединения, ни один из которых не подходит для использования в качестве входного аргумента . По этой причине входные объекты имеют в системе отдельный тип.
Это «официальная причина», но есть несколько практических причин, по которым вы не можете использовать тип объекта в качестве типа входного объекта или использовать тип объекта в качестве типа входного объекта:
Функциональность
Типы объектов и типы входных объектов имеют поля, однако эти поля имеют разные свойства, которые отражают, как эти типы используются схемой. Ваша схема потенциально будет определять аргументы и какую-то функцию преобразователя для полей типа объекта, но эти свойства не имеют смысла во входном контексте (т.е. вы не можете разрешить поле входного объекта - оно уже имеет явное значение) . Точно так же значения по умолчанию могут быть предоставлены только для полей типа входного объекта, но не для полей типа объекта.
Другими словами, это может показаться дублированием:
type Student {
name: String
grade: Grade
}
input StudentInput {
name: String
grade: Grade
}
Но добавление функций, специфичных для типов объектов или типов входных объектов, проясняет, что они ведут себя по-разному:
type Student {
name(preferred: Boolean): String
grade: Grade
}
input StudentInput {
name: String
grade: Grade = F
}
Ограничения системы типов
Типы в GraphQL сгруппированы по типам вывода и типам ввода. .
Типы вывода - это типы, которые могут быть возвращены как часть ответа, созданного службой GraphQL. Типы ввода - это типы, которые являются допустимыми входными данными для аргументов поля или директивы.
Эти две группы пересекаются (т.е. скаляры, перечисления, списки и ненулевые значения). Однако абстрактные типы, такие как объединения и интерфейсы, не имеют смысла во входном контексте и не могут использоваться в качестве входных данных. Разделение типов объектов и типов объектов ввода позволяет гарантировать, что абстрактный тип никогда не будет использоваться там, где ожидается тип ввода.
Схема проектирования
При представлении сущности в вашей схеме вполне вероятно, что некоторые сущности действительно будут «разделять поля» между соответствующими типами ввода и вывода:
type Student {
firstName: String
lastName: String
grade: Grade
}
input StudentInput {
firstName: String
lastName: String
grade: Grade
}
Однако типы объектов могут (и на самом деле часто делают) моделировать очень сложные структуры данных:
type Student {
fullName: String!
classes: [Class!]!
address: Address!
emergencyContact: Contact
# etc
}
Хотя эти структуры могут преобразовываться в соответствующие входные данные (мы создаем Student, поэтому мы также передаем объект, представляющий их адрес), часто они этого не делают - то есть, возможно, нам нужно указать классы учащихся по идентификатору класса и идентификатору раздела, а не по объект. Точно так же у нас могут быть поля, которые мы хотим вернуть, но не хотим изменять, или наоборот (например, password
поле).
Более того, даже для относительно простых сущностей мы часто предъявляем разные требования относительно допустимости значений NULL между типами объектов и их «двойниками» входных объектов. Часто мы хотим гарантировать, что поле также будет возвращено в ответе, но мы не хотим, чтобы те же поля были обязательными для нашего ввода. Например,
type Student {
firstName: String!
lastName: String!
}
input StudentInput {
firstName: String
lastName: String
}
Наконец, во многих схемах часто нет однозначного соответствия между типом объекта и типом входного объекта для данной сущности. Распространенным шаблоном является использование отдельных типов входных объектов для различных операций для дальнейшей точной настройки проверки входных данных на уровне схемы:
input CreateUserInput {
firstName: String!
lastName: String!
email: String!
password: String!
}
input UpdateUserInput {
email: String
password: String
}
Все эти примеры иллюстрируют важный момент - хотя тип входного объекта может иногда отражать тип объекта, у вас гораздо меньше шансов увидеть это в производственных схемах из-за бизнес-требований.