De la spécification :
Le type d'objet GraphQL (ObjectTypeDefinition)... ne peut pas être réutilisé [en tant qu'entrée], car les types d'objet peuvent contenir des champs qui définissent des arguments ou contiennent des références à des interfaces et des unions, ce qui n'est pas approprié pour une utilisation en tant qu'argument d'entrée. Pour cette raison, les objets d'entrée ont un type distinct dans le système.
C'est la "raison officielle", mais il y a plusieurs raisons pratiques pour lesquelles vous ne pouvez pas utiliser un type d'objet comme type d'objet d'entrée ou utiliser un type d'objet comme type d'objet d'entrée :
Fonctionnalité
Les types d'objets et les types d'objets d'entrée ont tous deux des champs, mais ces champs ont des propriétés différentes qui reflètent la façon dont ces types sont utilisés par le schéma. Votre schéma définira potentiellement des arguments et une sorte de fonction de résolution pour les champs d'un type d'objet, mais ces propriétés n'ont pas de sens dans un contexte d'entrée (c'est-à-dire que vous ne pouvez pas résoudre un champ d'un objet d'entrée -- il a déjà une valeur explicite). De même, les valeurs par défaut ne peuvent être fournies que pour les champs de type objet d'entrée, et non pour les champs de type objet.
En d'autres termes, cela peut sembler faire double emploi :
type Student {
name: String
grade: Grade
}
input StudentInput {
name: String
grade: Grade
}
Mais l'ajout de fonctionnalités spécifiques aux types d'objets ou aux types d'objets d'entrée montre clairement qu'ils se comportent différemment :
type Student {
name(preferred: Boolean): String
grade: Grade
}
input StudentInput {
name: String
grade: Grade = F
}
Limites du système de type
Les types dans GraphQL sont regroupés en types de sortie et types de saisie .
Les types de sortie sont des types qui peuvent être retournés dans le cadre d'une réponse produite par un service GraphQL. Les types d'entrée sont des types qui sont des entrées valides pour les arguments des champs ou des directives.
Il y a un chevauchement entre ces deux groupes (c'est-à-dire scalaires, enums, listes et non-nulls). Cependant, types abstraits comme les unions et les interfaces n'ont pas de sens dans un contexte d'entrée et ne peuvent pas être utilisées comme entrées. La séparation des types d'objets et des types d'objets d'entrée vous permet de vous assurer qu'un type abstrait n'est jamais utilisé là où un type d'entrée est attendu.
Conception des schémas
Lorsque vous représentez une entité dans votre schéma, il est probable que certaines entités "partagent des champs" entre leurs types d'entrée et de sortie respectifs :
type Student {
firstName: String
lastName: String
grade: Grade
}
input StudentInput {
firstName: String
lastName: String
grade: Grade
}
Cependant, les types d'objets peuvent modéliser (et le font souvent en réalité) des structures de données très complexes :
type Student {
fullName: String!
classes: [Class!]!
address: Address!
emergencyContact: Contact
# etc
}
Bien que ces structures mai Si les données sont souvent traduites par des entrées appropriées (nous créons un étudiant, nous transmettons donc également un objet représentant son adresse), ce n'est souvent pas le cas -- par exemple, nous avons peut-être besoin de spécifier les classes de l'étudiant par l'ID de classe et l'ID de section, et non par un objet. De même, nous pouvons avoir des champs que nous voulons renvoyer, mais que nous ne voulons pas modifier, ou vice versa (comme un objet password
).
En outre, même pour des entités relativement simples, nous avons souvent des exigences différentes en matière de nullité entre les types d'objets et leurs objets d'entrée "équivalents". Souvent, nous voulons garantir qu'un champ sera également renvoyé dans une réponse, mais nous ne voulons pas rendre ces mêmes champs obligatoires dans notre entrée. Par exemple,
type Student {
firstName: String!
lastName: String!
}
input StudentInput {
firstName: String
lastName: String
}
Enfin, dans de nombreux schémas, il n'y a souvent pas de correspondance biunivoque entre le type d'objet et le type d'objet d'entrée pour une entité donnée. Un modèle commun consiste à utiliser des types d'objets d'entrée distincts pour différentes opérations afin d'affiner la validation des entrées au niveau du schéma :
input CreateUserInput {
firstName: String!
lastName: String!
email: String!
password: String!
}
input UpdateUserInput {
email: String
password: String
}
Tous ces exemples illustrent un point important : si un type d'objet d'entrée peut parfois refléter un type d'objet, il est beaucoup moins probable que cela se produise dans les schémas de production en raison des exigences commerciales.
60 votes
Les objets d'entrée doivent être sérialisables. Comme les objets de sortie peuvent contenir des cycles, ils ne peuvent pas être réutilisés pour les entrées.
2 votes
Jesse, il semble que la réponse soit suffisante ! Vous pouvez répondre et je le marque ainsi.
0 votes
Je me demande s'il est possible de combiner des interfaces avec celui-ci.