

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# GraphQL et architecture AWS AppSync
<a name="graphql-overview"></a>

**Note**  
Ce guide part du principe que l'utilisateur possède une connaissance pratique du style architectural REST. Nous vous recommandons de consulter cette rubrique ainsi que d'autres rubriques relatives au front-end avant de travailler avec AWS AppSync GraphQL et.

GraphQL est un langage de requête et de manipulation pour. APIs GraphQL fournit une syntaxe flexible et intuitive pour décrire les exigences relatives aux données et les interactions. Il permet aux développeurs de demander exactement ce dont ils ont besoin et d'obtenir des résultats prévisibles. Il permet également d'accéder à de nombreuses sources en une seule demande, réduisant ainsi le nombre d'appels réseau et les besoins en bande passante, réduisant ainsi l'autonomie de la batterie et les cycles de processeur consommés par les applications. 

Les mises à jour des données sont simplifiées grâce à des mutations, ce qui permet aux développeurs de décrire la manière dont les données doivent changer. GraphQL facilite également la configuration rapide de solutions en temps réel via des abonnements. Toutes ces fonctionnalités combinées, associées à de puissants outils de développement, font de GraphQL un outil essentiel pour gérer les données des applications.

GraphQL est une alternative à REST. RESTful l'architecture est actuellement l'une des solutions les plus populaires pour la communication client-serveur. Il est centré sur le concept selon lequel vos ressources (données) sont exposées par une URL. Ils URLs peuvent être utilisés pour accéder aux données et les manipuler par le biais d'opérations CRUD (création, lecture, mise à jour, suppression) sous la forme de méthodes HTTP telles que `GET``POST`, et`DELETE`. L'avantage de REST est qu'il est relativement simple à apprendre et à mettre en œuvre. Vous pouvez rapidement vous configurer RESTful APIs pour appeler un large éventail de services. 

Cependant, la technologie devient de plus en plus complexe. Alors que les applications, les outils et les services commencent à évoluer pour un public mondial, le besoin d'architectures rapides et évolutives est d'une importance capitale. REST présente de nombreuses lacunes lorsqu'il s'agit d'opérations évolutives. Consultez ce [cas d'utilisation](https://aws.amazon.com/blogs/architecture/what-to-consider-when-modernizing-apis-with-graphql-on-aws/) pour un exemple.

Dans les sections suivantes, nous passerons en revue certains des concepts qui l'entourent RESTful APIs. Nous présenterons ensuite GraphQL et son fonctionnement.

Pour plus d'informations sur GraphQL et les avantages de la migration vers GraphQL AWS, consultez le guide de [décision relatif aux implémentations de GraphQL](https://aws.amazon.com/graphql/guide/).

**Topics**
+ [Qu'est-ce qu'une API](what-is-an-api.md)
+ [Qu'est-ce que REST](what-is-rest.md)
+ [Qu'est-ce que GraphQL](what-is-graphql.md)
+ [Comparaison entre REST et GraphQL](comparing-rest-graphql.md)
+ [Pourquoi utiliser GraphQL sur REST](why-use-graphql.md)
+ [Composants d'une API GraphQL](api-components.md)
+ [Propriétés supplémentaires de GraphQL](graphql-properties.md)

# Qu'est-ce qu'une API ?
<a name="what-is-an-api"></a>

Une interface de programmation d'applications (API) définit les règles que vous devez suivre pour communiquer avec d'autres systèmes logiciels. Les développeurs exposent ou créent de APIs manière à ce que d'autres applications puissent communiquer avec leurs applications par programmation. Par exemple, l'application de feuille de temps expose une API qui demande le nom complet d'un employé et une plage de dates. Lorsqu'il reçoit ces informations, il traite en interne la feuille de temps de l'employé et renvoie le nombre d'heures travaillées dans cette plage de dates.

Vous pouvez considérer une API Web comme une passerelle entre les clients et les ressources sur le Web.

## Clients
<a name="what-is-a-client"></a>

Les clients sont des utilisateurs qui souhaitent accéder à des informations depuis le Web. Le client peut être une personne ou un système logiciel utilisant l'API. Par exemple, les développeurs peuvent écrire des programmes qui accèdent aux données météorologiques d'un système météorologique. Vous pouvez également accéder aux mêmes données depuis votre navigateur lorsque vous visitez directement le site Web de la météo.

## Ressources
<a name="what-is-a-resource"></a>

Les ressources sont les informations que les différentes applications fournissent à leurs clients. Les ressources peuvent être des images, des vidéos, du texte, des chiffres ou tout autre type de données. La machine qui fournit la ressource au client est également appelée serveur. Organisations ont l' APIs habitude de partager des ressources et de fournir des services Web tout en maintenant la sécurité, le contrôle et l'authentification. En outre, APIs aidez-les à déterminer quels clients ont accès à des ressources internes spécifiques.

# Qu'est-ce que REST ?
<a name="what-is-rest"></a>

À un niveau élevé, le transfert d'état représentatif (REST) est une architecture logicielle qui impose des conditions quant au fonctionnement d'une API. REST a été initialement créé comme ligne directrice pour gérer la communication sur un réseau complexe tel qu'Internet. Vous pouvez utiliser l'architecture basée sur REST pour prendre en charge des communications fiables et performantes à grande échelle. Vous pouvez facilement l'implémenter et le modifier, en apportant de la visibilité et de la portabilité multiplateforme à n'importe quel système d'API.

Les développeurs d'API peuvent concevoir APIs en utilisant plusieurs architectures différentes. APIs qui suivent le style architectural REST sont appelés REST APIs. Les services Web qui implémentent l'architecture REST sont appelés services RESTful Web. Le terme RESTful API fait généralement référence au RESTful Web APIs. Cependant, vous pouvez utiliser les termes API REST et RESTful API de manière interchangeable.

Voici certains des principes du style architectural REST :

## Interface uniforme
<a name="uniform-interface"></a>

L'interface uniforme est essentielle à la conception de tout RESTful service Web. Cela indique que le serveur transfère les informations dans un format standard. La ressource formatée est appelée représentation dans REST. Ce format peut être différent de la représentation interne de la ressource sur l'application serveur. Par exemple, le serveur peut stocker des données sous forme de texte mais les envoyer dans un format de représentation HTML.

L'interface uniforme impose quatre contraintes architecturales :

1.  Les demandes doivent identifier les ressources. Pour ce faire, ils utilisent un identifiant de ressource uniforme. 

1.  Les clients disposent de suffisamment d'informations dans la représentation des ressources pour modifier ou supprimer la ressource s'ils le souhaitent. Le serveur répond à cette condition en envoyant des métadonnées qui décrivent plus en détail la ressource. 

1.  Les clients reçoivent des informations sur la manière de poursuivre le traitement de la représentation. Le serveur y parvient en envoyant des messages autodescriptifs contenant des métadonnées indiquant comment le client peut les utiliser au mieux. 

1.  Les clients reçoivent des informations sur toutes les autres ressources connexes dont ils ont besoin pour effectuer une tâche. Le serveur y parvient en envoyant des hyperliens dans la représentation afin que les clients puissent découvrir dynamiquement davantage de ressources. 

## Apatridie
<a name="statelessness"></a>

Dans l'architecture REST, l'apatridie fait référence à une méthode de communication dans laquelle le serveur exécute chaque demande client indépendamment de toutes les demandes précédentes. Les clients peuvent demander des ressources dans n'importe quel ordre, et chaque demande est apatride ou isolée des autres demandes. Cette contrainte de conception de l'API REST implique que le serveur peut parfaitement comprendre et traiter la demande à chaque fois. 

## Système en couches
<a name="layered-system"></a>

Dans une architecture système en couches, le client peut se connecter à d'autres intermédiaires autorisés entre le client et le serveur, et il continuera à recevoir des réponses du serveur. Les serveurs peuvent également transmettre des demandes à d'autres serveurs. Vous pouvez concevoir votre service RESTful Web pour qu'il s'exécute sur plusieurs serveurs dotés de plusieurs couches telles que la sécurité, les applications et la logique métier, en travaillant ensemble pour répondre aux demandes des clients. Ces couches restent invisibles pour le client.

## Possibilité de mise en cache
<a name="cacheability"></a>

RESTful les services Web prennent en charge la mise en cache, qui consiste à stocker certaines réponses sur le client ou sur un intermédiaire afin d'améliorer le temps de réponse du serveur. Supposons, par exemple, que vous consultiez un site Web dont les images d'en-tête et de pied de page sont communes à chaque page. Chaque fois que vous visitez une nouvelle page Web, le serveur doit renvoyer les mêmes images. Pour éviter cela, le client met en cache ou stocke ces images après la première réponse, puis les utilise directement depuis le cache. RESTful les services Web contrôlent la mise en cache en utilisant des réponses d'API qui se définissent comme pouvant être mises en cache ou non mises en cache.

## Qu'est-ce qu'une RESTful API ?
<a name="what-is-a-restful-api"></a>

RESTful L'API est une interface utilisée par deux systèmes informatiques pour échanger des informations en toute sécurité sur Internet. La plupart des applications métiers doivent communiquer avec d'autres applications internes et tierces pour effectuer diverses tâches. Par exemple, pour générer des fiches de paie mensuelles, votre système de comptes interne doit partager des données avec le système bancaire de votre client afin d'automatiser la facturation et de communiquer avec une application interne de feuille de temps. RESTful APIs soutiennent cet échange d'informations car ils respectent des normes de communication logicielle sécurisées, fiables et efficaces.

## Comment RESTful APIs travaillez-vous ?
<a name="how-do-restful-apis-work"></a>

La fonction de base d'une RESTful API est la même que celle de naviguer sur Internet. Le client contacte le serveur à l'aide de l'API lorsqu'il a besoin d'une ressource. Les développeurs d'API expliquent comment le client doit utiliser l'API REST dans la documentation de l'API de l'application serveur. Voici les étapes générales pour tout appel d'API REST :

1.  Le client envoie une demande au serveur. Le client suit la documentation de l'API pour formater la demande d'une manière compréhensible par le serveur. 

1.  Le serveur authentifie le client et confirme qu'il a le droit de faire cette demande. 

1.  Le serveur reçoit la demande et la traite en interne. 

1.  Le serveur renvoie une réponse au client. La réponse contient des informations qui indiquent au client si la demande a été acceptée. La réponse inclut également toute information demandée par le client. 

Les détails de la demande et de la réponse à l'API REST varient légèrement en fonction de la manière dont les développeurs d'API conçoivent l'API.

# Qu'est-ce que GraphQL ?
<a name="what-is-graphql"></a>

GraphQL est à la fois un langage de requête APIs et un environnement d'exécution pour exécuter ces requêtes. GraphQL permet aux clients de demander exactement les données dont ils ont besoin, offrant ainsi une alternative plus flexible et plus efficace à REST dans de nombreux scénarios. Contrairement à REST, qui repose sur des points de terminaison prédéfinis, GraphQL utilise un point de terminaison unique où les clients peuvent spécifier leurs exigences en matière de données sous forme de requêtes et de mutations. 

Voir [Composants d'une API GraphQL](https://docs.aws.amazon.com/appsync/latest/devguide/api-components.html) pour plus d'informations sur la structure de APIs GraphQL.

# Comparaison entre REST et GraphQL
<a name="comparing-rest-graphql"></a>

APIs (Interfaces de programmation d'applications) jouent un rôle crucial dans la facilitation de l'échange de données entre les applications. Comme indiqué précédemment, deux approches de conception importantes APIs ont vu le jour : GraphQL et REST. Bien que les deux aient pour objectif fondamental de permettre la communication client-serveur, ils diffèrent considérablement dans leur mise en œuvre et leurs cas d'utilisation.

GraphQL et REST partagent plusieurs caractéristiques clés : 

1. **Modèle client-serveur** : les deux utilisent une architecture client-serveur pour l'échange de données. 

1. **Apatridie** : aucun des deux ne conserve les informations de session client entre les demandes. 

1. **Basé sur HTTP** : les deux utilisent généralement le protocole HTTP comme protocole de communication sous-jacent. 

1. **Conception axée sur les ressources** : les deux conçoivent leur échange de données autour des ressources, qui font référence à toute donnée ou objet auquel le client peut accéder et manipuler via l'API. 

1. **Flexibilité du format de données** : JSON est le format d'échange de données le plus couramment utilisé dans les deux cas, bien que d'autres formats tels que XML et HTML soient également pris en charge. 

1. Indépendamment du **langage et de la base** de données : les deux peuvent fonctionner avec n'importe quel langage de programmation ou structure de base de données, ce qui les rend hautement interopérables. 

1. **Support de mise en cache** : les deux prennent en charge la mise en cache, ce qui permet aux clients et aux serveurs de stocker les données fréquemment consultées pour améliorer les performances. 

Tout en partageant certains principes fondamentaux, GraphQL et REST diffèrent considérablement dans leur approche de la conception des API et de la récupération de données :

1. **Structure des demandes et récupération des données**

   REST utilise différentes méthodes HTTP (GET, POST, PUT, DELETE) pour effectuer des opérations sur les ressources. Cela nécessite souvent plusieurs points de terminaison pour différentes ressources, ce qui peut entraîner des inefficiences dans la récupération des données. Par exemple, l'exécution d'une opération GET pour récupérer les données d'un utilisateur peut entraîner une extraction excessive ou insuffisante des données. Pour obtenir les données correctes, il est possible de procéder à une troncature ou à plusieurs opérations. 

   GraphQL utilise un point de terminaison unique pour toutes les opérations. Il s'appuie sur des requêtes pour récupérer des données et des mutations pour modifier les données. Les clients peuvent utiliser des requêtes pour récupérer exactement les données dont ils ont besoin en une seule demande, ce qui réduit la surcharge réseau en minimisant le transfert de données. 

1. **Schéma côté serveur**

   REST ne nécessite pas de schéma côté serveur, mais un schéma peut être défini en option pour une conception et une documentation d'API efficaces.

   GraphQL utilise un schéma fortement typé côté serveur pour définir les données et les services de données. Le schéma, écrit en langage de définition de schéma (SDL) GraphQL, inclut des types d'objets et des champs pour chaque objet, ainsi que des fonctions de résolution côté serveur qui définissent les opérations pour chaque champ.

1. **Contrôle de version**

   REST inclut souvent le versionnement dans l'URL, ce qui peut entraîner la gestion simultanée de plusieurs versions d'API. La gestion des versions n'est pas obligatoire, mais elle peut aider à éviter des modifications intempestives. 

   GraphQL favorise une évolution continue de l'API sans gestion explicite des versions en exigeant une rétrocompatibilité. Les champs supprimés renvoient des messages d'erreur, tandis que les balises de dépréciation suppriment progressivement les anciens champs et renvoient des messages d'avertissement. 

1. **Gestion des erreurs** 

   REST est faiblement typé, ce qui nécessite que la gestion des erreurs soit intégrée au code environnant. Cela peut ne pas identifier automatiquement les erreurs liées au type (par exemple, l'analyse d'un nombre sous forme de texte). 

   En revanche, GraphQL est fortement typé et nécessite une définition de schéma complète. Cela permet à votre service d'identifier automatiquement de nombreuses erreurs de demande avec un niveau de détail élevé.

1. **Cas d'utilisation**

   REST est mieux adapté pour : 
   + Applications plus petites avec des exigences de données moins complexes. 
   + Scénarios dans lesquels les données et les opérations sont utilisées de la même manière par tous les clients. 
   + Applications ne nécessitant pas de requêtes de données complexes. 

   GraphQL est mieux adapté pour : 
   + Scénarios avec bande passante limitée, où il est crucial de minimiser les demandes et les réponses. 
   + Applications comportant plusieurs sources de données qui doivent être combinées sur un seul point de terminaison. 
   + Cas où les demandes des clients varient considérablement et nécessitent des structures de réponse différentes.

   Notez qu'il est possible d'utiliser GraphQL et REST APIs au sein d'une même application pour différents domaines de fonctionnalités. En outre, vous pouvez mettre à niveau une RESTful API pour inclure des fonctionnalités GraphQL sans réécriture complète. Consultez [Comment créer des résolveurs GraphQL pour les sources de AWS données pour](https://aws.amazon.com/graphql/resolvers/) un exemple.

# Pourquoi utiliser GraphQL sur REST ?
<a name="why-use-graphql"></a>

REST est l'un des styles architecturaux fondamentaux du Web APIs. Cependant, à mesure que le monde devient de plus en plus interconnecté, la nécessité de développer des applications robustes et évolutives deviendra un problème de plus en plus pressant. Bien que REST soit souvent utilisé pour créer du Web APIs, les RESTful implémentations présentent plusieurs inconvénients récurrents qui ont été identifiés :

1. **Demandes de données** : en utilisant RESTful APIs, vous demanderez généralement les données dont vous avez besoin via des points de terminaison. Le problème survient lorsque vous avez des données qui ne sont peut-être pas aussi bien regroupées. Les données dont vous avez besoin se trouvent peut-être derrière plusieurs couches d'abstraction, et le seul moyen de les récupérer est d'utiliser plusieurs points de terminaison, ce qui implique de faire plusieurs demandes pour extraire toutes les données.

1. **Extraire et sous-extraction : pour aggraver** les problèmes liés aux demandes multiples, les données de chaque point de terminaison sont strictement définies, ce qui signifie que vous retournerez les données définies pour cette API, même si vous ne le vouliez pas techniquement.

   Cela peut entraîner *une extraction excessive*, ce qui signifie que nos demandes renvoient des données superflues. Supposons, par exemple, que vous demandiez des données sur le personnel de l'entreprise et que vous souhaitiez connaître les noms des employés d'un service donné. Le point de terminaison qui renvoie les données contiendra les noms, mais il peut également contenir d'autres données, telles que le titre du poste ou la date de naissance. Comme l'API est fixe, vous ne pouvez pas simplement demander les noms ; le reste des données est fourni avec.

   La situation inverse dans laquelle nous ne renvoyons pas suffisamment de données est appelée *sous-extraction*. Pour obtenir toutes les données demandées, vous devrez peut-être faire plusieurs demandes au service. Selon la structure des données, vous pourriez être confronté à des requêtes inefficaces entraînant des problèmes tels que le redoutable problème n\$11.

1. **Itérations de développement lentes** : de nombreux développeurs RESTful APIs les adaptent au flux de leurs applications. Cependant, au fur et à mesure que leurs applications se développent, le front et le backend peuvent nécessiter des modifications importantes. Par conséquent, il est APIs possible qu'elles ne s'adaptent plus à la forme des données de manière efficace ou percutante. Cela entraîne des itérations de produit plus lentes en raison de la nécessité de modifier l'API.

1. **Performances à grande échelle** : en raison de ces problèmes aggravants, l'évolutivité sera affectée dans de nombreux domaines. Les performances du côté de l'application peuvent être affectées car vos demandes renverront trop ou pas assez de données (ce qui se traduira par un plus grand nombre de demandes). Ces deux situations sollicitent inutilement le réseau, ce qui se traduit par de mauvaises performances. Du côté des développeurs, la vitesse de développement peut être réduite car vous APIs êtes fixe et ne correspondez plus aux données qu'ils demandent.

L'argument de vente de GraphQL est de surmonter les inconvénients de REST. Voici quelques-unes des principales solutions proposées par GraphQL aux développeurs :

1. **Points de terminaison uniques** : GraphQL utilise un point de terminaison unique pour interroger les données. Il n'est pas nécessaire d'en créer plusieurs APIs pour s'adapter à la forme des données. Cela se traduit par une diminution du nombre de demandes transitant par le réseau.

1. **Récupération** : GraphQL résout les problèmes récurrents liés à la surextraction et à la sous-extraction en définissant simplement les données dont vous avez besoin. GraphQL vous permet de façonner les données en fonction de vos besoins afin de ne recevoir que ce que vous avez demandé.

1. **Abstraction** : GraphQL APIs contient quelques composants et systèmes qui décrivent les données à l'aide d'une norme indépendante du langage. En d'autres termes, la forme et la structure des données sont normalisées afin que le front-end et le back-end sachent comment elles seront envoyées sur le réseau. Cela permet aux développeurs des deux côtés de travailler avec les systèmes de GraphQL et non de les contourner.

1. **Itérations rapides** : en raison de la standardisation des données, des modifications peuvent ne pas être nécessaires d'un côté du développement à l'autre. Par exemple, les modifications de présentation du frontend peuvent ne pas entraîner de modifications importantes du backend car GraphQL permet de modifier facilement la spécification des données. Vous pouvez simplement définir ou modifier la forme des données pour répondre aux besoins de l'application au fur et à mesure de sa croissance. Cela se traduit par une réduction des travaux de développement potentiels.

Ce ne sont là que quelques-uns des avantages de GraphQL. Dans les sections suivantes, vous découvrirez comment GraphQL est structuré et quelles sont les propriétés qui en font une alternative unique à REST.

# Composants d'une API GraphQL
<a name="api-components"></a>

Une API GraphQL standard est composée d'un schéma unique qui gère la forme des données qui seront interrogées. Votre schéma est lié à une ou plusieurs de vos sources de données, telles qu'une base de données ou une fonction Lambda. Entre les deux se trouvent un ou plusieurs résolveurs qui gèrent la logique métier de vos demandes. Chaque composant joue un rôle important dans votre implémentation de GraphQL. Les sections suivantes présentent ces trois composants et le rôle qu'ils jouent dans le service GraphQL.

![\[GraphQL API components: schema, resolvers, and data sources interconnected with AppSync.\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/images/appsync-architecture-graphql-api.png)


**Topics**
+ [Schémas GraphQL](schema-components.md)
+ [Sources de données](data-source-components.md)
+ [Résolveurs](resolver-components.md)

# Schémas GraphQL
<a name="schema-components"></a>

Le schéma GraphQL est la base d'une API GraphQL. Il sert de modèle qui définit la forme de vos données. Il s'agit également d'un contrat entre votre client et votre serveur qui définit la manière dont vos données seront récupérées et and/or modifiées.

Les schémas GraphQL sont écrits dans le langage SDL (*Schema Definition Language*). SDL est composé de types et de champs dotés d'une structure établie :
+ **Types** : Les types sont la façon dont GraphQL définit la forme et le comportement des données. GraphQL prend en charge une multitude de types qui seront expliqués plus loin dans cette section. Chaque type défini dans votre schéma contiendra sa propre portée. Le champ d'application comportera un ou plusieurs champs pouvant contenir une valeur ou une logique qui sera utilisée dans votre service GraphQL. Les types remplissent de nombreux rôles différents, les plus courants étant les objets ou les scalaires (types de valeurs primitives).
+ **Champs** : les champs existent dans le cadre d'un type et contiennent la valeur demandée au service GraphQL. Elles sont très similaires aux variables d'autres langages de programmation. La forme des données que vous définissez dans vos champs déterminera la manière dont les données sont structurées lors d'une request/response opération. Cela permet aux développeurs de prévoir ce qui sera renvoyé sans savoir comment le backend du service est implémenté.

Pour visualiser à quoi ressemblerait un schéma, examinons le contenu d'un schéma GraphQL simple. Dans le code de production, votre schéma se trouve généralement dans un fichier appelé `schema.graphql` ou`schema.json`. Supposons que nous étudions un projet qui implémente un service GraphQL. Ce projet stocke les données du personnel de l'entreprise, et le `schema.graphql` fichier est utilisé pour récupérer les données sur le personnel et ajouter du nouveau personnel à une base de données. Le code peut ressembler à ceci :

------
#### [ schema.graphql ]

```
type Person {                                  
   id: ID!
   name: String                                  
   age: Int
}
type Query {                                   
  people: [Person]
}
type Mutation {
  addPerson(id: ID!, name: String, age: Int): Person
}
```

------

Nous pouvons voir qu'il existe trois types définis dans le schéma :`Person`,`Query`, et`Mutation`. En regardant`Person`, nous pouvons deviner qu'il s'agit du modèle d'une instance d'un employé de l'entreprise, ce qui ferait de ce type un objet. À l'intérieur de son champ d'application`id`, nous voyons`name`, et`age`. Ce sont les champs qui définissent les propriétés d'un`Person`. Cela signifie que notre source de données stocke chacun `Person` d'eux `name` en tant que type `String` scalaire (primitif) et `age` en tant que type `Int` scalaire (primitif). Il `id` agit comme un identifiant spécial et unique pour chacun d'entre eux`Person`. Il s'agit également d'une valeur obligatoire, comme indiqué par le `!` symbole.

Les deux types d'objets suivants se comportent différemment. GraphQL réserve quelques mots clés pour des types d'objets spéciaux qui définissent la manière dont les données seront renseignées dans le schéma. Un `Query` type récupérera les données de la source. Dans notre exemple, notre requête peut récupérer `Person` des objets d'une base de données. Cela peut vous rappeler des `GET` opérations RESTful terminologiques. A `Mutation` modifiera les données. Dans notre exemple, notre mutation peut ajouter d'autres `Person` objets à la base de données. Cela peut vous rappeler des opérations qui changent d'état, comme `PUT` ou`POST`. Les comportements de tous les types d'objets spéciaux seront expliqués plus loin dans cette section.

Supposons que `Query` dans notre exemple, quelque chose soit extrait de la base de données. Si nous examinons les champs de`Query`, nous voyons un champ appelé`people`. La valeur de son champ est`[Person]`. Cela signifie que nous voulons récupérer une instance de `Person` dans la base de données. Cependant, l'ajout de crochets signifie que nous voulons renvoyer une liste de toutes les `Person` instances et pas seulement une instance spécifique.

Le `Mutation` type est chargé d'effectuer des opérations de changement d'état telles que la modification des données. Une mutation est chargée d'effectuer une opération de changement d'état sur la source de données. Dans notre exemple, notre mutation contient une opération appelée `addPerson` qui ajoute un nouvel `Person` objet à la base de données. La mutation utilise un `Person` et attend une entrée pour les `age` champs `id``name`, et.

À ce stade, vous vous demandez peut-être comment `addPerson` fonctionnent de telles opérations sans implémentation de code, étant donné qu'elles sont censées avoir un certain comportement et ressemblent beaucoup à une fonction avec un nom de fonction et des paramètres. Actuellement, cela ne fonctionne pas car un schéma ne sert que de déclaration. Pour implémenter le comportement de`addPerson`, il faudrait y ajouter un résolveur. Un résolveur est une unité de code exécutée chaque fois que le champ associé (dans ce cas, l'`addPerson`opération) est appelé. Si vous souhaitez utiliser une opération, vous devrez ajouter l'implémentation du résolveur à un moment donné. D'une certaine manière, vous pouvez considérer l'opération du schéma comme la déclaration de fonction et le résolveur comme la définition. Les résolveurs seront expliqués dans une section différente.

Cet exemple montre uniquement les méthodes les plus simples utilisées par un schéma pour manipuler les données. Vous créez des applications complexes, robustes et évolutives en tirant parti des fonctionnalités de GraphQL et. AWS AppSync Dans la section suivante, nous définirons les différents types et comportements de champ que vous pouvez utiliser dans votre schéma.

# Types de GraphQL
<a name="graphql-types"></a>

GraphQL prend en charge de nombreux types différents. Comme vous l'avez vu dans la section précédente, les types définissent la forme ou le comportement de vos données. Ils sont les éléments de base d'un schéma GraphQL. 

Les types peuvent être classés en entrées et en sorties. Les entrées sont des types autorisés à être transmis comme argument pour les types d'objets spéciaux (`Query`,, etc.)`Mutation`, tandis que les types de sortie sont strictement utilisés pour stocker et renvoyer des données. Vous trouverez ci-dessous une liste des types et de leurs catégories :
+ **Objets** : un objet contient des champs décrivant une entité. Par exemple, un objet peut être quelque chose comme un `book` avec des champs décrivant ses caractéristiques comme `authorName``publishingYear`, etc. Ce sont strictement des types de sortie.
+ **Scalaires** : ce sont des types primitifs tels que int, string, etc. Ils sont généralement affectés à des champs. En utilisant le `authorName` champ comme exemple, on pourrait lui attribuer le `String` scalaire pour stocker un nom tel que « John Smith ». Les scalaires peuvent être des types d'entrée et de sortie.
+ **Entrées** : Les entrées vous permettent de transmettre un groupe de champs en tant qu'argument. Leur structure est très similaire à celle des objets, mais ils peuvent être transmis en tant qu'arguments à des objets spéciaux. Les entrées vous permettent de définir des scalaires, des énumérations et d'autres entrées dans son champ d'application. Les entrées ne peuvent être que des types d'entrée.
+ **Objets spéciaux** : les objets spéciaux effectuent des opérations de changement d'état et effectuent l'essentiel du travail. Il existe trois types d'objets spéciaux : requête, mutation et abonnement. Les requêtes récupèrent généralement des données ; les mutations manipulent les données ; les abonnements ouvrent et maintiennent une connexion bidirectionnelle entre les clients et les serveurs pour une communication constante. Les objets spéciaux ne sont ni en entrée ni en sortie étant donné leur fonctionnalité.
+ **Enums : Les** énumérations sont des listes prédéfinies de valeurs légales. Si vous appelez une énumération, ses valeurs ne peuvent être que celles définies dans son champ d'application. Par exemple, si vous aviez une énumération intitulée `trafficLights` représentant une liste de feux de circulation, elle pourrait avoir des valeurs telles que `redLight` et `greenLight` mais non`purpleLight`. Un vrai feu de signalisation n'aura qu'un nombre limité de signaux. Vous pouvez donc utiliser l'énumération pour les définir et les forcer à être les seules valeurs légales lors du référencement`trafficLight`. Les énumérations peuvent être des types d'entrée et de sortie.
+ **Unions/interfaces** : les syndicats vous permettent de renvoyer un ou plusieurs éléments dans une demande en fonction des données demandées par le client. Par exemple, si vous aviez un `Book` type avec un `title` champ et un `Author` type avec un `name` champ, vous pourriez créer une union entre les deux types. Si votre client souhaitait rechercher dans une base de données l'expression « Jules César », le syndicat pourrait renvoyer *Jules César* (la pièce de William Shakespeare) du `Book` `title` et *Jules César* (l'auteur de *Commentarii de Bello* Gallico) du. `Author` `name` Les unions ne peuvent être que des types de sortie.

  Les interfaces sont des ensembles de champs que les objets doivent implémenter. Cela ressemble un peu aux interfaces des langages de programmation tels que Java où vous devez implémenter les champs définis dans l'interface. Supposons, par exemple, que vous ayez créé une interface appelée `Book` contenant un `title` champ. Supposons que vous ayez créé par la suite un type appelé « `Novel` that implemented »`Book`. Vous `Novel` devrez inclure un `title` champ. Cependant, vous `Novel` pouvez également inclure d'autres champs ne figurant pas dans l'interface, tels que `pageCount` ou`ISBN`. Les interfaces ne peuvent être que des types de sortie.

Les sections suivantes expliquent le fonctionnement de chaque type dans GraphQL.

## Objets
<a name="object-components"></a>

Les objets GraphQL sont le type principal que vous verrez dans le code de production. Dans GraphQL, vous pouvez considérer un objet comme un regroupement de différents champs (similaires aux variables d'autres langages), chaque champ étant défini par un type (généralement un scalaire ou un autre objet) pouvant contenir une valeur. Les objets représentent une unité de données qui peut retrieved/manipulated provenir de l'implémentation de votre service.

Les types d'objets sont déclarés à l'aide du `Type` mot clé. Modifions légèrement notre exemple de schéma :

```
type Person {
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}

type Occupation {
  title: String
}
```

Les types d'objets présentés ici sont `Person` et`Occupation`. Chaque objet possède ses propres champs avec ses propres types. L'une des fonctionnalités de GraphQL est la possibilité de définir d'autres types de champs. Vous pouvez voir que le `occupation` champ `Person` contient un type d'`Occupation`objet. Nous pouvons établir cette association car GraphQL ne fait que décrire les données et non l'implémentation du service.

## Scalaires
<a name="scalar-components"></a>

Les scalaires sont essentiellement des types primitifs qui contiennent des valeurs. Dans AWS AppSync, il existe deux types de scalaires : les scalaires GraphQL par défaut et les scalaires AWS AppSync . Les scalaires sont généralement utilisés pour stocker des valeurs de champs dans des types d'objets. Les types GraphQL par défaut incluent`Int`, `Float` `String``Boolean`, et. `ID` Reprenons l'exemple précédent :

```
type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}

type Occupation {
  title: String
}
```

En distinguant les `title` champs `name` et, les deux contiennent un `String` scalaire. `Name`pourrait renvoyer une valeur de chaîne comme « `John Smith` » et le titre pourrait renvoyer quelque chose comme « `firefighter` ». Certaines implémentations de GraphQL prennent également en charge les scalaires personnalisés utilisant le `Scalar` mot-clé et implémentant le comportement du type. Cependant, les scalaires personnalisés **ne sont AWS AppSync actuellement pas pris en charge**. Pour une liste des scalaires, voir [Types de scalaires](https://docs.aws.amazon.com//appsync/latest/devguide/scalars.html) dans. AWS AppSync

## Inputs
<a name="input-components"></a>

En raison du concept des types d'entrée et de sortie, certaines restrictions s'appliquent lors de la transmission d'arguments. Les types qui doivent généralement être transmis, en particulier les objets, sont restreints. Vous pouvez utiliser le type de saisie pour contourner cette règle. Les entrées sont des types contenant des scalaires, des énumérations et d'autres types d'entrées.

Les entrées sont définies à l'aide du `input` mot clé :

```
type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}

type Occupation {
  title: String
}

input personInput { 
  id: ID!
  name: String
  age: Int
  occupation: occupationInput
}

input occupationInput {
  title: String
}
```

Comme vous pouvez le constater, nous pouvons avoir des entrées séparées qui imitent le type d'origine. Ces entrées seront souvent utilisées dans le cadre de vos opérations sur le terrain comme suit :

```
type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}

type Occupation {
  title: String
}

input occupationInput {
  title: String
}

type Mutation {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput): Person
}
```

Notez que nous sommes toujours en train de passer `occupationInput` à la place de `Occupation` pour créer un`Person`. 

Ce n'est qu'un des scénarios pour les entrées. Ils n'ont pas nécessairement besoin de copier les objets 1:1, et dans le code de production, vous ne les utiliserez probablement pas de cette manière. Il est recommandé de tirer parti des schémas GraphQL en définissant uniquement ce que vous devez saisir en tant qu'arguments.

De plus, les mêmes entrées peuvent être utilisées dans plusieurs opérations, mais nous vous déconseillons de le faire. Chaque opération doit idéalement contenir sa propre copie unique des entrées au cas où les exigences du schéma changeraient.

## Objets spéciaux
<a name="special-object-components"></a>

GraphQL réserve quelques mots clés à des objets spéciaux qui définissent une partie de la logique métier régissant la manière dont votre schéma affichera retrieve/manipulate les données. Il peut tout au plus y avoir un seul de ces mots clés dans un schéma. Ils servent de points d'entrée pour toutes les données demandées que vos clients exécutent avec votre service GraphQL. 

Les objets spéciaux sont également définis à l'aide du `type` mot-clé. Bien qu'ils soient utilisés différemment des types d'objets classiques, leur implémentation est très similaire.

------
#### [ Queries ]

Les requêtes sont très similaires aux `GET` opérations dans la mesure où elles effectuent une extraction en lecture seule pour obtenir des données de votre source. Dans GraphQL, `Query` définit tous les points d'entrée pour les clients effectuant des requêtes sur votre serveur. Il y en aura toujours un `Query` dans votre implémentation GraphQL.

Voici les types `Query` d'objets modifiés que nous avons utilisés dans notre précédent exemple de schéma :

```
type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
type Occupation {
  title: String
}
type Query {                                   
  people: [Person]
}
```

Notre `Query` contient un champ appelé `people` qui renvoie une liste d'`Person`instances à partir de la source de données. Supposons que nous devions modifier le comportement de notre application et que nous devions maintenant renvoyer une liste contenant uniquement les `Occupation` instances dans un but distinct. Nous pourrions simplement l'ajouter à la requête :

```
type Query {                                   
  people: [Person]
  occupations: [Occupation]
}
```

Dans GraphQL, nous pouvons traiter notre requête comme une source unique de requêtes. Comme vous pouvez le constater, cela est potentiellement beaucoup plus simple que RESTful les implémentations qui peuvent utiliser différents points de terminaison pour obtenir la même chose (`.../api/1/people`et`.../api/1/occupations`).

En supposant que nous ayons une implémentation de résolveur pour cette requête, nous pouvons maintenant effectuer une requête réelle. Tant que le `Query` type existe, nous devons l'appeler explicitement pour qu'il s'exécute dans le code de l'application. Cela peut être fait en utilisant le `query` mot clé :

```
query getItems {
   people {
      name
   }
   occupations {
      title
   }
}
```

Comme vous pouvez le voir, cette requête est appelée `getItems` et renvoie `people` (une liste d'`Person`objets) et `occupations` (une liste d'`Occupation`objets). Dans`people`, nous renvoyons uniquement le `name` champ de chacun`Person`, tandis que nous renvoyons le `title` champ de chacun`Occupation`. La réponse peut ressembler à ceci :

```
{
  "data": {
    "people": [
      {
        "name": "John Smith"
      },
      {
        "name": "Andrew Miller"
      },
      .
      .
      .
    ],
    "occupations": [
      {
        "title": "Firefighter"
      },
      {
        "title": "Bookkeeper"
      },
      .
      .
      .
    ]
  }
}
```

L'exemple de réponse montre comment les données suivent la forme de la requête. Chaque entrée récupérée est répertoriée dans le champ d'application du champ. `people`et `occupations` renvoient les éléments sous forme de listes séparées. Bien que cela soit utile, il peut être plus pratique de modifier la requête pour renvoyer une liste des noms et professions des personnes :

```
query getItems {
   people {
      name   
      occupation {
        title
      }
}
```

Il s'agit d'une modification légale car notre `Person` type contient un `occupation` champ de type`Occupation`. Une fois répertorié dans le champ de portée de`people`, nous `Person` renvoyons chacun `name` avec le nom associé `Occupation` à`title`. La réponse peut ressembler à ceci :

```
}
  "data": {
    "people": [
      {
        "name": "John Smith",
        "occupation": {
          "title": "Firefighter"
        }
      },
      {
        "name": "Andrew Miller",
        "occupation": {
          "title": "Bookkeeper"
        }
      },
      .
      .
      .
    ]
  }
}
```

------
#### [ Mutations ]

Les mutations sont similaires aux opérations de changement d'état telles que `PUT` ou`POST`. Ils exécutent une opération d'écriture pour modifier les données de la source, puis récupèrent la réponse. Ils définissent vos points d'entrée pour les demandes de modification de données. Contrairement aux requêtes, une mutation peut être incluse ou non dans le schéma en fonction des besoins du projet. Voici la mutation tirée de l'exemple de schéma :

```
type Mutation {
  addPerson(id: ID!, name: String, age: Int): Person
}
```

Le `addPerson` champ représente un point d'entrée qui ajoute un `Person` à la source de données. `addPerson`est le nom du champ ;`id`,`name`, et `age` sont les paramètres ; et `Person` est le type de retour. Rétrospectivement, le `Person` type :

```
type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}
```

Nous avons ajouté le `occupation` champ. Cependant, nous ne pouvons pas définir ce champ sur `Occupation` directement car les objets ne peuvent pas être transmis en tant qu'arguments ; il s'agit uniquement de types de sortie. Nous devrions plutôt transmettre une entrée avec les mêmes champs en tant qu'argument :

```
input occupationInput {
  title: String
}
```

 Nous pouvons également facilement mettre à jour notre `addPerson` pour l'inclure en tant que paramètre lors de la création de nouvelles `Person` instances :

```
type Mutation {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput): Person
}
```

Voici le schéma mis à jour :

```
type Person { 
  id: ID!
  name: String
  age: Int
  occupation: Occupation
}

type Occupation {
  title: String
}

input occupationInput {
  title: String
}

type Mutation {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput): Person
}
```

Notez que le `title` champ `occupation` sera transmis `occupationInput` pour terminer la création de l'objet au `Person` lieu de l'`Occupation`objet d'origine. En supposant que nous ayons une implémentation de résolveur pour`addPerson`, nous pouvons maintenant effectuer une véritable mutation. Tant que le `Mutation` type existe, nous devons l'appeler explicitement pour qu'il s'exécute dans le code de l'application. Cela peut être fait en utilisant le `mutation` mot clé :

```
mutation createPerson {
  addPerson(id: ID!, name: String, age: Int, occupation: occupationInput) {
    name
    age
    occupation {
      title
    }
  }
}
```

Cette mutation est appelée`createPerson`, et `addPerson` c'est l'opération. Pour en créer un nouveau`Person`, nous pouvons saisir les arguments pour `id``name`,`age`, et`occupation`. Dans le cadre de`addPerson`, nous pouvons également voir d'autres domaines tels que `name``age`, etc. Voici votre réponse ; ce sont les champs qui seront renvoyés une fois l'`addPerson`opération terminée. Voici la dernière partie de l'exemple :

```
mutation createPerson {
  addPerson(id: "1", name: "Steve Powers", age: "50", occupation: "Miner") {
    id
    name
    age
    occupation {
      title
    }
  }
}
```

En utilisant cette mutation, le résultat pourrait ressembler à ceci :

```
{
  "data": {
    "addPerson": {
      "id": "1",
      "name": "Steve Powers",
      "age": "50",
      "occupation": {
        "title": "Miner"
      }
    }
  }
}
```

Comme vous pouvez le constater, la réponse a renvoyé les valeurs que nous avions demandées dans le même format que celui défini dans notre mutation. Il est recommandé de renvoyer toutes les valeurs modifiées afin de réduire la confusion et d'éviter d'avoir à effectuer d'autres requêtes à l'avenir. Les mutations vous permettent d'inclure plusieurs opérations dans son champ d'application. Ils seront exécutés séquentiellement dans l'ordre indiqué dans la mutation. Par exemple, si nous créons une autre opération appelée `addOccupation` qui ajoute des titres de poste à la source de données, nous pouvons l'appeler dans la mutation suivante`addPerson`. `addPerson`sera traité en premier, suivi de`addOccupation`.

------
#### [ Subscriptions ]

Les abonnements [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications)permettent d'établir une connexion bidirectionnelle durable entre le serveur et ses clients. Généralement, un client s'abonne ou écoute le serveur. Chaque fois que le serveur effectue une modification côté serveur ou exécute un événement, le client abonné reçoit les mises à jour. Ce type de protocole est utile lorsque plusieurs clients sont abonnés et doivent être informés des modifications apportées au serveur ou à d'autres clients. Par exemple, les abonnements peuvent être utilisés pour mettre à jour les flux de réseaux sociaux. Il peut y avoir deux utilisateurs, l'utilisateur A et l'utilisateur B, qui sont tous deux abonnés aux mises à jour automatiques des notifications chaque fois qu'ils reçoivent des messages directs. L'utilisateur A sur le client A pourrait envoyer un message direct à l'utilisateur B sur le client B. Le client de l'utilisateur A enverrait le message direct, qui serait traité par le serveur. Le serveur enverrait ensuite le message direct au compte de l'utilisateur B tout en envoyant une notification automatique au client B.

Voici un exemple `Subscription` que nous pourrions ajouter à l'exemple de schéma :

```
type Subscription {                                   
  personAdded: Person
}
```

Le `personAdded` champ envoie un message aux clients abonnés chaque fois qu'un nouveau message `Person` est ajouté à la source de données. En supposant que nous ayons une implémentation de résolveur pour`personAdded`, nous pouvons désormais utiliser l'abonnement. Tant que le `Subscription` type existe, nous devons l'appeler explicitement pour qu'il s'exécute dans le code de l'application. Cela peut être fait en utilisant le `subscription` mot clé :

```
subscription personAddedOperation {
  personAdded {
    id
    name
  }
}
```

L'abonnement est appelé`personAddedOperation`, et l'opération l'est`personAdded`. `personAdded`renverra les `name` champs `id` et des nouvelles `Person` instances. En regardant l'exemple de mutation, nous avons ajouté une `Person` en utilisant cette opération :

```
addPerson(id: "1", name: "Steve Powers", age: "50", occupation: "Miner")
```

Si nos clients étaient abonnés aux mises à jour des nouvelles versions`Person`, ils pourraient voir ceci après les `addPerson` essais :

```
{
  "data": {
    "personAdded": {
      "id": "1",
      "name": "Steve Powers"
    }
  }
}
```

Vous trouverez ci-dessous un résumé de ce que proposent les abonnements :

Les abonnements sont des canaux bidirectionnels qui permettent au client et au serveur de recevoir des mises à jour rapides mais régulières. Ils utilisent généralement le WebSocket protocole, qui crée des connexions standardisées et sécurisées.

Les abonnements sont souples dans la mesure où ils réduisent les frais de configuration des connexions. Une fois abonné, un client peut simplement continuer à utiliser cet abonnement pendant de longues périodes. Ils utilisent généralement les ressources informatiques de manière efficace en permettant aux développeurs d'adapter la durée de vie de l'abonnement et de configurer les informations qui seront demandées.

En général, les abonnements permettent au client de souscrire plusieurs abonnements à la fois. En ce qui concerne AWS AppSync, les abonnements ne sont utilisés que pour recevoir des mises à jour en temps réel du AWS AppSync service. Ils ne peuvent pas être utilisés pour effectuer des requêtes ou des mutations.

La principale alternative aux abonnements est le sondage, qui envoie des requêtes à intervalles réguliers pour demander des données. Ce processus est généralement moins efficace que les abonnements et met beaucoup de pression à la fois sur le client et sur le backend.

------

Une chose qui n'a pas été mentionnée dans notre exemple de schéma est le fait que vos types d'objets spéciaux doivent également être définis dans une `schema` racine. Ainsi, lorsque vous exportez un schéma au AWS AppSync format, il peut ressembler à ceci :

------
#### [ schema.graphql ]

```
schema {
  query: Query
  mutation: Mutation
  subscription: Subscription
}

.
.
.

type Query {                                   
  # code goes here
}
type Mutation {                                   
  # code goes here
}
type Subscription {                                   
  # code goes here
}
```

------

## Énumération
<a name="enum-components"></a>

Les énumérations, ou énumérations, sont des scalaires spéciaux qui limitent les arguments juridiques qu'un type ou un champ peut avoir. Cela signifie que chaque fois qu'une énumération est définie dans le schéma, son type ou champ associé sera limité aux valeurs de l'énumération. Les énumérations sont sérialisées sous forme de scalaires de chaînes. Notez que différents langages de programmation peuvent gérer les énumérations GraphQL différemment. Par exemple, n' JavaScript a pas de support d'énumération natif, de sorte que les valeurs d'énumération peuvent être mappées à des valeurs int à la place.

Les énumérations sont définies à l'aide du `enum` mot-clé. Voici un exemple :

```
enum trafficSignals {
  solidRed
  solidYellow
  solidGreen
  greenArrowLeft
  ...
}
```

Lors de l'appel de l'`trafficLights`énumération, le ou les arguments ne peuvent être que `solidRed``solidYellow`,`solidGreen`, etc. Il est courant d'utiliser des énumérations pour décrire des éléments qui offrent un nombre de choix distinct mais limité.

## Unions/Interfaces
<a name="union-interface-components"></a>

Voir [Interfaces et unions](https://docs.aws.amazon.com/appsync/latest/devguide/interfaces-and-unions.html) dans GraphQL.

# Champs GraphQL
<a name="graphql-fields"></a>

Les champs existent dans le cadre d'un type et contiennent la valeur demandée au service GraphQL. Elles sont très similaires aux variables d'autres langages de programmation. Par exemple, voici un type d'`Person`objet :

```
type Person {                                  
   name: String                                  
   age: Int
}
```

Dans ce cas, les champs sont `name` `age` et contiennent respectivement une `Int` valeur `String` et. Les champs d'objet tels que ceux présentés ci-dessus peuvent être utilisés comme entrées dans les champs (opérations) de vos requêtes et mutations. Par exemple, consultez ce qui `Query` suit :

```
type Query {                                   
  people: [Person]
}
```

Le `people` champ demande toutes les instances de `Person` depuis la source de données. Lorsque vous ajoutez ou extrayez un fichier `Person` dans votre serveur GraphQL, vous pouvez vous attendre à ce que les données suivent le format de vos types et de vos champs, c'est-à-dire que la structure de vos données dans le schéma détermine la manière dont elles seront structurées dans votre réponse :

```
}
  "data": {
    "people": [
      {
        "name": "John Smith",
        "age": "50"
      },
      {
        "name": "Andrew Miller",
        "age": "60"
      },
      .
      .
      .
    ]
  }
}
```

Les champs jouent un rôle important dans la structuration des données. Quelques propriétés supplémentaires expliquées ci-dessous peuvent être appliquées aux champs pour une personnalisation accrue.

## Lists
<a name="list-components"></a>

Les listes renvoient tous les éléments d'un type spécifié. Une liste peut être ajoutée au type d'un champ à l'aide de crochets `[]` : 

```
type Person { 
  name: String
  age: Int
}
type Query {                                   
  people: [Person]
}
```

Dans`Query`, les crochets qui l'entourent `Person` indiquent que vous souhaitez renvoyer toutes les instances `Person` de la source de données sous forme de tableau. Dans la réponse, les `age` valeurs `name` et de chacune `Person` seront renvoyées sous forme de liste unique et délimitée :

```
}
  "data": {
    "people": [
      {
        "name": "John Smith",         # Data of Person 1
        "age": "50"
      },
      {
        "name": "Andrew Miller",      # Data of Person 2
        "age": "60"
      },
      .                               # Data of Person N
      .
      .
    ]
  }
}
```

Vous n'êtes pas limité aux types d'objets spéciaux. Vous pouvez également utiliser des listes dans les champs des types d'objets classiques.

## Non nuls
<a name="non-null-components"></a>

Les valeurs non nulles indiquent un champ qui ne peut pas être nul dans la réponse. Vous pouvez attribuer à un champ une valeur non nulle en utilisant le `!` symbole :

```
type Person { 
  name: String!
  age: Int
}
type Query {                                   
  people: [Person]
}
```

Le `name` champ ne peut pas être explicitement nul. Si vous interrogiez la source de données et que vous fournissiez une entrée nulle pour ce champ, une erreur serait générée.

Vous pouvez combiner des listes et des valeurs non nulles. Comparez les requêtes suivantes :

```
type Query {                                   
  people: [Person!]      # Use case 1
}

.
.
.

type Query {                                   
  people: [Person]!      # Use case 2
}

.
.
.

type Query {                                   
  people: [Person!]!     # Use case 3
}
```

Dans le cas d'utilisation 1, la liste ne peut pas contenir d'éléments nuls. Dans le cas d'utilisation 2, la liste elle-même ne peut pas être définie sur null. Dans le cas d'utilisation 3, la liste et ses éléments ne peuvent pas être nuls. Cependant, dans tous les cas, vous pouvez toujours renvoyer des listes vides.

Comme vous pouvez le constater, GraphQL comporte de nombreux composants mobiles. Dans cette section, nous avons présenté la structure d'un schéma simple ainsi que les différents types et champs qu'un schéma prend en charge. Dans la section suivante, vous découvrirez les autres composants d'une API GraphQL et leur fonctionnement avec le schéma.

# Sources de données
<a name="data-source-components"></a>

Dans la section précédente, nous avons appris qu'un schéma définit la forme de vos données. Cependant, nous n'avons jamais expliqué d'où venaient ces données. Dans les projets réels, votre schéma est comme une passerelle qui gère toutes les demandes adressées au serveur. Lorsqu'une demande est faite, le schéma agit comme le point de terminaison unique qui interagit avec le client. Le schéma accèdera aux données de la source de données, les traitera et les transmettra au client. Consultez l'infographie ci-dessous :

![\[GraphQL schema integrating multiple Services AWS for a single endpoint API architecture.\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/images/aws-flow-infographic.png)


AWS AppSync et GraphQL implémentent superbement des solutions Backend For Frontend (BFF). Ils travaillent en tandem pour réduire la complexité à grande échelle en faisant abstraction du backend. Si votre service utilise différentes sources de données et/ou microservices, vous pouvez essentiellement éliminer une partie de la complexité en définissant la forme des données de chaque source (sous-graphe) dans un schéma unique (supergraphe). Cela signifie que votre API GraphQL n'est pas limitée à l'utilisation d'une seule source de données. Vous pouvez associer autant de sources de données que vous le souhaitez à votre API GraphQL et spécifier dans votre code la manière dont elles interagiront avec le service.

Comme vous pouvez le voir dans l'infographie, le schéma GraphQL contient toutes les informations dont les clients ont besoin pour demander des données. Cela signifie que tout peut être traité en une seule demande plutôt que plusieurs requêtes comme c'est le cas avec REST. Ces demandes passent par le schéma, qui est le seul point de terminaison du service. Lorsque les demandes sont traitées, un résolveur (expliqué dans la section suivante) exécute son code pour traiter les données de la source de données correspondante. Lorsque la réponse est renvoyée, le sous-graphe lié à la source de données est rempli avec les données du schéma. 

AWS AppSync prend en charge de nombreux types de sources de données différents. Dans le tableau ci-dessous, nous allons décrire chaque type, énumérer certains de ses avantages et fournir des liens utiles pour plus de contexte.


| Source de données | Description | Avantages | Informations supplémentaires | 
| --- | --- | --- | --- | 
| Amazon DynamoDB | « Amazon DynamoDB est un service de base de données NoSQL entièrement géré qui fournit des performances rapides et prévisibles avec une évolutivité sans faille. DynamoDB vous libère des charges administratives liées à l'exploitation et à la mise à l'échelle d'une base de données distribuée de façon que vous n'ayez pas à vous soucier de divers aspects tels que l'approvisionnement, le paramétrage, la configuration, la réplication, le matériel, les correctifs logiciels ou la mise à l'échelle de cluster. DynamoDB propose également le chiffrement au repos, ce qui élimine la charge opérationnelle et la complexité liées à la protection des données sensibles. » |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  | 
| AWS Lambda | « AWS Lambda  est un service de calcul qui vous permet d'exécuter du code sans provisionner ni gérer de serveurs.Lambda exécute le code sur une infrastructure informatique à haute disponibilité et effectue toute l'administration des ressources informatiques, y compris la maintenance des serveurs et du système d'exploitation, l'allocation et la mise à l'échelle automatique des capacités, ainsi que la mise à l'échelle automatique et la journalisation. Avec Lambda, il vous suffit de fournir votre code dans l'un des environnements d'exécution de langage pris en charge par Lambda. » |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  | 
| OpenSearch | « Amazon OpenSearch Service est un service géré qui facilite le déploiement, l'exploitation et le dimensionnement de OpenSearch clusters dans le AWS cloud. Amazon OpenSearch Service prend en charge OpenSearch les anciens logiciels Elasticsearch OSS (jusqu'à la version 7.10, dernière version open source du logiciel). Lorsque vous créez un cluster, vous avez la possibilité de choisir le moteur de recherche que vous voulez utiliser.**OpenSearch**est un moteur de recherche et d'analyse entièrement open source pour des cas d'utilisation tels que l'analyse des journaux, la surveillance des applications en temps réel et l'analyse du flux de clics. Pour plus d’informations, consultez la [documentation OpenSearch](https://opensearch.org/docs/).**Amazon OpenSearch Service** fournit toutes les ressources pour votre OpenSearch cluster et le lance. Il détecte et remplace également automatiquement les nœuds de OpenSearch service défaillants, réduisant ainsi les frais associés aux infrastructures autogérées. Vous pouvez faire évoluer votre cluster en un seul appel d'API ou en quelques clics dans la console. » |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  | 
| Points de terminaison HTTP | Vous pouvez utiliser des points de terminaison HTTP comme sources de données. AWS AppSync peut envoyer des demandes aux points de terminaison avec les informations pertinentes telles que les paramètres et la charge utile. La réponse HTTP sera exposée au résolveur, qui renverra la réponse finale une fois ses opérations terminées. |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  | 
| Amazon EventBridge | « EventBridge  est un service sans serveur qui utilise des événements pour connecter les composants de l'application entre eux, ce qui vous permet de créer plus facilement des applications évolutives pilotées par des événements. Utilisez-le pour acheminer des événements provenant de sources telles que des applications locales, des AWS services et des logiciels tiers vers des applications grand public au sein de votre entreprise. EventBridge fournit un moyen simple et cohérent d'ingérer, de filtrer, de transformer et de diffuser des événements afin que vous puissiez créer rapidement de nouvelles applications. » |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  | 
| Bases de données relationnelles | « Amazon Relational Database Service (Amazon RDS) est un service Web qui facilite la configuration, l'exploitation et le dimensionnement d'une base de données relationnelle dans le cloud. AWS Il fournit une capacité redimensionnable et rentable pour une base de données relationnelle standard et gère les tâches d'administration de base de données courantes. » |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  | 
| Aucune source de données | Si vous n'avez pas l'intention d'utiliser un service de source de données, vous pouvez le configurer surnone. Une source de none données, bien qu'elle soit toujours explicitement classée comme source de données, n'est pas un support de stockage. Malgré cela, il est toujours utile dans certains cas pour la manipulation et le transfert de données. |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  |  [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/data-source-components.html)  | 

**Astuce**  
Pour plus d'informations sur la façon dont les sources de données interagissent avec elles AWS AppSync, voir [Joindre une source de données](https://docs.aws.amazon.com//appsync/latest/devguide/attaching-a-data-source.html).

# Résolveurs
<a name="resolver-components"></a>

Dans les sections précédentes, vous avez découvert les composants du schéma et de la source de données. Nous devons maintenant examiner la manière dont le schéma et les sources de données interagissent. Tout commence par le résolveur.

Un résolveur est une unité de code qui gère la manière dont les données de ce champ seront résolues lorsqu'une demande est envoyée au service. Les résolveurs sont attachés à des champs spécifiques au sein de vos types dans votre schéma. Ils sont le plus souvent utilisés pour implémenter les opérations de changement d'état pour vos opérations de terrain de requête, de mutation et d'abonnement. Le résolveur traitera la demande d'un client, puis renverra le résultat, qui peut être un groupe de types de sortie tels que des objets ou des scalaires :

![\[GraphQL schema with resolvers connecting to various AWS data sources for a single endpoint.\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/images/aws-flow-infographic.png)


## Temps d'exécution du résolveur
<a name="resolver-components-runtime"></a>

Dans AWS AppSync, vous devez d'abord spécifier un environnement d'exécution pour votre résolveur. Un environnement d'exécution d'un résolveur indique l'environnement dans lequel un résolveur est exécuté. Il dicte également la langue dans laquelle vos résolveurs seront écrits. AWS AppSync supporte actuellement APPSYNC\$1JS pour JavaScript et Velocity Template Language (VTL). Consultez les [fonctionnalités JavaScript d'exécution pour les résolveurs et les fonctions](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html) JavaScript ou la [référence de l'utilitaire de modèle de mappage Resolver](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference.html) pour VTL.

## Structure du résolveur
<a name="resolver-components-structure"></a>

Du point de vue du code, les résolveurs peuvent être structurés de plusieurs manières. Il existe des résolveurs d'**unités** et de **pipelines**.

### Résolveurs d'unités
<a name="resolver-components-unit"></a>

Un résolveur d'unités est composé d'un code qui définit un seul gestionnaire de requêtes et de réponses qui est exécuté sur une source de données. Le gestionnaire de demandes prend un objet de contexte comme argument et renvoie la charge utile de la demande utilisée pour appeler votre source de données. Le gestionnaire de réponses reçoit une charge utile en retour de la source de données avec le résultat de la demande exécutée. Le gestionnaire de réponse transforme la charge utile en réponse GraphQL pour résoudre le champ GraphQL.

![\[GraphQL request flow showing request and response handlers interacting with a data source.\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/images/unit-resolver-js.png)


### Résolveurs de pipelines
<a name="resolver-components-pipeline"></a>

Lors de la mise en œuvre de résolveurs de pipeline, ils suivent une structure générale :
+ **Avant l'étape** : lorsqu'une demande est faite par le client, les données de la demande sont transmises aux résolveurs des champs de schéma utilisés (généralement vos requêtes, mutations, abonnements). Le résolveur commencera à traiter les données de la demande à l'aide d'un gestionnaire avant étape, qui permet d'effectuer certaines opérations de prétraitement avant que les données ne passent par le résolveur.
+ **Fonction (s)** : Une fois l'étape précédente exécutée, la demande est transmise à la liste des fonctions. La première fonction de la liste s'exécutera sur la source de données. Une fonction est un sous-ensemble du code de votre résolveur contenant son propre gestionnaire de requêtes et de réponses. Un gestionnaire de demandes prendra les données de la demande et effectuera des opérations sur la source de données. Le gestionnaire de réponses traitera la réponse de la source de données avant de la renvoyer à la liste. S'il existe plusieurs fonctions, les données de la demande seront envoyées à la fonction suivante de la liste à exécuter. Les fonctions de la liste seront exécutées en série dans l'ordre défini par le développeur. Une fois que toutes les fonctions ont été exécutées, le résultat final est transmis à l'étape suivante.
+ **Étape suivante** : L'étape suivante est une fonction de gestion qui vous permet d'effectuer certaines opérations finales sur la réponse de la fonction finale avant de la transmettre à la réponse GraphQL.

![\[GraphQL request flow diagram showing interactions between request, data sources, and response components.\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/images/appsync-js-resolver-logic.png)


## Structure du gestionnaire du résolveur
<a name="resolver-components-handlers"></a>

Les gestionnaires sont généralement des fonctions appelées `Request` et `Response` :

```
export function request(ctx) {
    // Code goes here
}

export function response(ctx) {
    // Code goes here
}
```

Dans un résolveur d'unités, il n'y aura qu'un seul ensemble de ces fonctions. Dans un résolveur de pipeline, il y en aura un ensemble pour les étapes avant et après et un ensemble supplémentaire par fonction. Pour visualiser à quoi cela pourrait ressembler, examinons un `Query` type simple :

```
type Query {
	helloWorld: String!
}
```

Il s'agit d'une requête simple avec un champ appelé `helloWorld` type`String`. Supposons que nous voulions toujours que ce champ renvoie la chaîne « Hello World ». Pour implémenter ce comportement, nous devons ajouter le résolveur dans ce champ. Dans un résolveur d'unités, nous pourrions ajouter quelque chose comme ceci :

```
export function request(ctx) {
    return {}
}

export function response(ctx) {
    return "Hello World"
}
```

`request`Vous pouvez simplement laisser ce champ vide car nous ne demandons ni ne traitons de données. Nous pouvons également supposer que notre source de données l'est`None`, ce qui indique que ce code n'a pas besoin d'effectuer d'invocations. La réponse renvoie simplement « Hello World ». Pour tester ce résolveur, nous devons faire une demande en utilisant le type de requête :

```
query helloWorldTest {
  helloWorld
}
```

Il s'agit d'une requête appelée `helloWorldTest` qui renvoie le `helloWorld` champ. Lorsqu'il est exécuté, le résolveur de `helloWorld` champs exécute et renvoie également la réponse :

```
{
  "data": {
    "helloWorld": "Hello World"
  }
}
```

Renvoyer des constantes comme celle-ci est la chose la plus simple que vous puissiez faire. En réalité, vous allez renvoyer des entrées, des listes, etc. Voici un exemple plus complexe :

```
type Book {
  id: ID!
  title: String
}

type Query {
  getBooks: [Book]
}
```

Nous renvoyons ici une liste de`Books`. Supposons que nous utilisions une table DynamoDB pour stocker les données d'un livre. Nos gestionnaires peuvent ressembler à ceci :

```
/**
 * Performs a scan on the dynamodb data source
 */
export function request(ctx) {
  return { operation: 'Scan' };
}

/**
 * return a list of scanned post items
 */
export function response(ctx) {
  return ctx.result.items;
}
```

Notre demande a utilisé une opération de numérisation intégrée pour rechercher toutes les entrées de la table, a stocké les résultats dans le contexte, puis les a transmis à la réponse. La réponse a pris les éléments du résultat et les a renvoyés dans la réponse :

```
{
  "data": {
    "getBooks": {
      "items": [
        {
          "id": "abcdefgh-1234-1234-1234-abcdefghijkl",
          "title": "book1"
        },
        {
          "id": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee",
          "title": "book2"
        },

        ...

      ]
    }
  }
}
```

## Contexte du résolveur
<a name="resolver-components-context"></a>

Dans un résolveur, chaque étape de la chaîne de gestionnaires doit connaître l'état des données des étapes précédentes. Le résultat d'un gestionnaire peut être stocké et transmis à un autre en tant qu'argument. GraphQL définit quatre arguments de base du résolveur :


****  

| Arguments de base du résolveur | Description | 
| --- | --- | 
| obj, root, parent, etc. | Le résultat du parent. | 
| args | Les arguments fournis au champ dans la requête GraphQL. | 
| context | Une valeur qui est fournie à chaque résolveur et contient des informations contextuelles importantes telles que l'utilisateur actuellement connecté ou l'accès à une base de données. | 
| info | Une valeur qui contient des informations spécifiques au champ pertinentes pour la requête en cours ainsi que les détails du schéma. | 

Dans AWS AppSync, l'argument `[context](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html)` (ctx) peut contenir toutes les données mentionnées ci-dessus. Il s'agit d'un objet créé par demande et qui contient des données telles que les informations d'identification d'autorisation, les données de résultats, les erreurs, les métadonnées des demandes, etc. Le contexte est un moyen facile pour les programmeurs de manipuler les données provenant d'autres parties de la requête. Reprenez cet extrait :

```
/**
 * Performs a scan on the dynamodb data source
 */
export function request(ctx) {
  return { operation: 'Scan' };
}

/**
 * return a list of scanned post items
 */
export function response(ctx) {
  return ctx.result.items;
}
```

La requête reçoit le contexte (ctx) comme argument ; il s'agit de l'état de la demande. Il effectue une analyse de tous les éléments d'un tableau, puis stocke le résultat dans le contexte dans`result`. Le contexte est ensuite transmis à l'argument de réponse, qui accède au `result` et renvoie son contenu.

## Requêtes et analyse syntaxique
<a name="resolver-ast"></a>

Lorsque vous envoyez une requête à votre service GraphQL, celle-ci doit passer par un processus d'analyse et de validation avant d'être exécutée. Votre demande sera analysée et traduite dans un arbre syntaxique abstrait. Le contenu de l'arborescence est validé en exécutant plusieurs algorithmes de validation par rapport à votre schéma. Après l'étape de validation, les nœuds de l'arbre sont parcourus et traités. Les résolveurs sont appelés, les résultats sont stockés dans le contexte et la réponse est renvoyée. Prenons, par exemple, cette requête :

```
query {
  Person {  //object type
    name  //scalar
    age   //scalar
  } 
}
```

Nous revenons `Person` avec un `name` et des `age` champs. Lors de l'exécution de cette requête, l'arborescence ressemblera à ceci :

![\[Hierarchical diagram showing query, Person, name, and age nodes connected by arrows.\]](http://docs.aws.amazon.com/fr_fr/appsync/latest/devguide/images/ast-1.png)


D'après l'arborescence, il apparaît que cette demande recherchera la racine `Query` dans le schéma. À l'intérieur de la requête, le `Person` champ sera résolu. D'après les exemples précédents, nous savons qu'il peut s'agir d'une entrée de l'utilisateur, d'une liste de valeurs, etc. Elle `Person` est très probablement liée à un type d'objet contenant les champs dont nous avons besoin (`name`et`age`). Une fois que ces deux champs enfants sont trouvés, ils sont résolus dans l'ordre indiqué (`name`suivi de`age`). Une fois que l'arbre est complètement résolu, la demande est terminée et sera renvoyée au client.

# Propriétés supplémentaires de GraphQL
<a name="graphql-properties"></a>

GraphQL repose sur plusieurs principes de conception visant à maintenir la simplicité et la robustesse à grande échelle.

## Déclaratif
<a name="declarative-property"></a>

GraphQL est déclaratif, ce qui signifie que l'utilisateur décrira (façonnera) les données en déclarant uniquement les champs qu'il souhaite interroger. La réponse renverra uniquement les données relatives à ces propriétés. Par exemple, voici une opération qui récupère un `Book` objet dans une table DynamoDB dont la valeur ISBN 13 est : `id` *9780199536061*

```
{
  getBook(id: "9780199536061") {
    name
    year
    author
  }
}
```

La réponse renverra les champs de la charge utile (`name`,`year`, et`author`) et rien d'autre :

```
{
  "data": {
    "getBook": {
      "name": "Anna Karenina",
      "year": "1878",
      "author": "Leo Tolstoy",
    }
  }
}
```

Grâce à ce principe de conception, GraphQL élimine les problèmes récurrents de surextraction et de sous-extraction auxquels REST est confronté dans les systèmes APIs complexes. Cela se traduit par une collecte de données plus efficace et une amélioration des performances du réseau.

## Hiérarchique
<a name="hierarchical-property"></a>

GraphQL est flexible dans la mesure où les données demandées peuvent être façonnées par l'utilisateur pour répondre aux besoins de l'application. Les données demandées suivent toujours les types et la syntaxe des propriétés définies dans votre API GraphQL. Par exemple, l'extrait suivant montre l'`getBook`opération avec une nouvelle portée de champ appelée `quotes` qui renvoie toutes les chaînes de guillemets stockées et les pages liées au : `Book` *9780199536061*

```
{
  getBook(id: "9780199536061") {
    name
    year
    author
    quotes {
      description
      page
    }
  }
}
```

L'exécution de cette requête renvoie le résultat suivant :

```
{
  "data": {
    "getBook": {
      "name": "Anna Karenina",
      "year": "1878",
      "author": "Leo Tolstoy",
      "quotes": [
         {
            "description": "The highest Petersburg society is essentially one: in it everyone knows everyone else, everyone even visits everyone else.",
            "page": 135
         },
         { 
            "description": "Happy families are all alike; every unhappy family is unhappy in its own way.",
            "page": 1
         },
         {        
            "description": "To Konstantin, the peasant was simply the chief partner in their common labor.",
            "page": 251
         }
      ]
    }
  }
}
```

Comme vous pouvez le constater, les `quotes` champs liés au livre demandé ont été renvoyés sous forme de tableau dans le même format que celui décrit dans notre requête. Bien qu'il n'ait pas été présenté ici, GraphQL présente l'avantage supplémentaire de ne pas être précis quant à l'emplacement des données qu'il récupère. `Books`et `quotes` pourraient être stockés séparément, mais GraphQL récupérera toujours les informations tant que l'association existe. Cela signifie que votre requête peut récupérer une multitude de données autonomes en une seule demande.

## Introspectif
<a name="introspective-property"></a>

GraphQL est autodocumenté, c'est-à-dire introspectif. Il prend en charge plusieurs opérations intégrées qui permettent aux utilisateurs de visualiser les types et les champs sous-jacents du schéma. Par exemple, voici un `Foo` type avec un `description` champ `date` et :

```
type Foo {
	date: String
	description: String
}
```

Nous pourrions utiliser l'`_type`opération pour trouver les métadonnées de saisie sous le schéma :

```
{
  __type(name: "Foo") {
    name                   # returns the name of the type
    fields {               # returns all fields in the type
      name                 # returns the name of each field
      type {               # returns all types for each field
        name               # returns the scalar type
      }
    }
  }
}
```

Cela renverra une réponse :

```
{
  "__type": {
    "name": "Foo",                     # The type name
    "fields": [
      {
        "name": "date",                # The date field
        "type": { "name": "String" }   # The date's type
      },
      {
        "name": "description",         # The description field
        "type": { "name": "String" }   # The description's type
      },
    ]
  }
}
```

Cette fonctionnalité peut être utilisée pour déterminer les types et les champs pris en charge par un schéma GraphQL particulier. GraphQL prend en charge une grande variété de ces opérations introspectives. Pour plus d'informations, consultez la section [Introspection](https://graphql.org/learn/introspection/).

## Typographie forte
<a name="strong-typing-property"></a>

GraphQL prend en charge la saisie forte grâce à son système de types et de champs. Lorsque vous définissez un élément dans votre schéma, il doit avoir un type qui peut être validé avant l'exécution. Il doit également suivre les spécifications de syntaxe de GraphQL. Ce concept n'est pas différent de la programmation dans d'autres langages. Par exemple, voici le `Foo` type précédent :

```
type Foo {
	date: String
	description: String
}
```

Nous pouvons voir que `Foo` c'est l'objet qui sera créé. À l'intérieur d'une instance de`Foo`, il y aura un `description` champ `date` et, tous deux de type `String` primitif (scalaire). Syntaxiquement, nous voyons que cela `Foo` a été déclaré et que ses champs existent dans son champ d'application. Cette combinaison de vérification de type et de syntaxe logique garantit que votre API GraphQL est concise et évidente. Les spécifications de typage et de syntaxe de GraphQL se trouvent [ici](https://spec.graphql.org/).