

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.

# Référence de type GraphQL
<a name="type-reference"></a>

Les types scalaires dans GraphQL représentent les valeurs primitives des feuilles dans un schéma GraphQL. Il s'agit des types de données les plus élémentaires qui se résolvent en une seule valeur. Contrairement aux types d'objets, les types scalaires ne peuvent pas avoir de sous-champs. GraphQL est fourni avec un ensemble de types scalaires par défaut : 
+ **Int** : un entier signé de 32 bits 
+ **Float** : valeur à virgule flottante signée en double précision 
+ **Chaîne** : une séquence de caractères UTF-8 
+ **Booléen : valeur** vraie ou fausse
+ **ID** : identifiant unique, souvent utilisé pour récupérer un objet ou comme clé pour un cache

Ces types scalaires servent de base pour les types plus complexes de votre schéma. Ils sont utilisés pour définir des champs contenant des valeurs simples et singulières. Outre ces scalaires intégrés, vous AWS AppSync propose des scalaires supplémentaires pour différents cas d'utilisation. 

Les interfaces et les unions dans GraphQL sont des types abstraits qui permettent une conception de schéma flexible et extensible. Ils fournissent des mécanismes permettant de regrouper les types associés et d'activer les requêtes polymorphes. Une interface dans GraphQL est un type abstrait qui définit un ensemble de champs qu'un type doit inclure pour implémenter l'interface. Il sert de contrat pour les objets en spécifiant un ensemble commun de champs que les types d'implémentation doivent avoir. Les interfaces sont utiles lorsque vous souhaitez renvoyer un objet ou un champ qui peut être de différents types, mais dont certains champs sont garantis. En revanche, une union dans GraphQL représente un type qui peut être l'un des nombreux types d'objets, mais ne définit aucun champ commun entre ces types. Les unions sont utiles lorsque vous devez renvoyer un champ qui peut être de plusieurs types, et ces types ne partagent pas nécessairement des champs communs. Les interfaces et les unions sont particulièrement utiles dans les scénarios où un champ peut renvoyer différents types de données, permettant aux clients de rechercher des champs spécifiques en fonction du type renvoyé. 

Cette section est utilisée comme référence pour les types de schéma.

**Rubriques**
+ [Types scalaires dans GraphQL](https://docs.aws.amazon.com/appsync/latest/devguide/scalars.html)
+ [Interfaces et unions dans GraphQL](https://docs.aws.amazon.com/appsync/latest/devguide/interfaces-and-unions.html)

# Types scalaires dans GraphQL
<a name="scalars"></a>

Un type d'objet GraphQL a un nom et des champs, et ces champs peuvent avoir des sous-champs. En fin de compte, les champs d'un type d'objet doivent être résolus en types *scalaires*, qui représentent les feuilles de la requête. Pour plus d'informations sur les types d'objets et les scalaires, consultez [Schémas et types](https://graphql.org/learn/schema/) sur le site Web de GraphQL.

Outre l'ensemble par défaut de scalaires GraphQL, vous pouvez AWS AppSync également utiliser les scalaires **définis par le service qui commencent par** le préfixe. *AWS* AWS AppSync ne prend pas en charge la création de scalaires **définis par l'utilisateur** (personnalisés). Vous devez utiliser la valeur par défaut ou des *AWS*scalaires. 

Vous ne pouvez pas l'utiliser *AWS*comme préfixe pour les types d'objets personnalisés.

La section suivante est une référence pour la saisie de schémas.

## Scalaires par défaut
<a name="graph-ql-base-scalars"></a>

GraphQL définit les scalaires par défaut suivants :

### Liste des scalaires par défaut
<a name="graph-ql-base-scalars-list"></a>

`ID`  
Identifiant unique d'un objet. Ce scalaire est sérialisé comme un `String` mais n'est pas censé être lisible par l'homme.

`String`  
Une séquence de caractères UTF-8.

`Int`  
Une valeur entière comprise entre - (2 31) et 2 31 -1.

`Float`  
Une valeur à virgule flottante IEEE 754.

`Boolean`  
Une valeur booléenne, `true` ou `false`.

## AWS AppSync scalaires
<a name="graph-ql-aws-appsync-scalars"></a>

AWS AppSync définit les scalaires suivants :

### AWS AppSync liste de scalaires
<a name="graph-ql-aws-appsync-scalars-list"></a>

`AWSDate`  
Chaîne de [date ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Calendar_dates) étendue au format`YYYY-MM-DD`.

`AWSTime`  
Chaîne [temporelle ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Times) étendue au format`hh:mm:ss.sss`.

`AWSDateTime`  
Chaîne de [date et d'heure ISO 8601](https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations) étendue au format`YYYY-MM-DDThh:mm:ss.sssZ`.

**Note**  
Les `AWSDateTime` scalaires `AWSDate``AWSTime`, et peuvent éventuellement inclure un [décalage de fuseau horaire](https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators). Par exemple, les valeurs `1970-01-01Z``1970-01-01-07:00`, et `1970-01-01+05:30` sont toutes valides pour`AWSDate`. Le décalage de fuseau horaire doit être soit `Z` (UTC), soit un décalage en heures et minutes (et éventuellement en secondes). Par exemple, `±hh:mm:ss`. Le champ des secondes dans le décalage horaire est considéré comme valide même s'il ne fait pas partie de la norme ISO 8601.

`AWSTimestamp`  
Une valeur entière représentant le nombre de secondes avant ou après`1970-01-01-T00:00Z`.

`AWSEmail`  
Une adresse e-mail au format `local-part@domain-part` défini par la [RFC 822](https://tools.ietf.org/html/rfc822).

`AWSJSON`  
Une chaîne JSON. Toute construction JSON valide est automatiquement analysée et chargée dans le code du résolveur sous forme de cartes, de listes ou de valeurs scalaires plutôt que sous forme de chaînes d'entrée littérales. Les chaînes sans guillemets ou le format JSON non valide entraînent une erreur de validation GraphQL.

`AWSPhone`  
Numéro de téléphone. Cette valeur est stockée sous forme de chaîne. Les numéros de téléphone peuvent contenir des espaces ou des traits d'union pour séparer les groupes de chiffres. Les numéros de téléphone sans code de pays sont supposés être des numéros américains ou nord-américains conformes au [plan de numérotation nord-américain (](https://en.wikipedia.org/wiki/North_American_Numbering_Plan)NANP).

`AWSURL`  
Une URL telle que définie par la [RFC 1738](https://tools.ietf.org/html/rfc1738). Par exemple, `https://www.amazon.com/dp/B000NZW3KC/` ou`mailto:example@example.com`. URLsdoit contenir un schéma (`http`,`mailto`) et ne peut pas contenir deux barres obliques (`//`) dans la partie chemin.

`AWSIPAddress`  
Une IPv6 adresse IPv4 ou une adresse valide. IPv4 les adresses sont attendues en notation à quatre points (). `123.12.34.56` IPv6 les adresses sont attendues dans un format non entre crochets et séparés par des deux-points (). `1a2b:3c4b::1234:4567` Vous pouvez inclure un suffixe CIDR facultatif (`123.45.67.89/16`) pour indiquer le masque de sous-réseau.

## Exemple d'utilisation du schéma
<a name="example-schema-usage"></a>

L'exemple de schéma GraphQL suivant utilise tous les scalaires personnalisés comme « objet » et montre les modèles de demande et de réponse du résolveur pour les opérations de base de type put, get et list. Enfin, l'exemple montre comment vous pouvez l'utiliser lors de l'exécution de requêtes et de mutations.

```
type Mutation {
    putObject(
        email: AWSEmail,
        json: AWSJSON,
        date: AWSDate,
        time: AWSTime,
        datetime: AWSDateTime,
        timestamp: AWSTimestamp,
        url: AWSURL,
        phoneno: AWSPhone,
        ip: AWSIPAddress
    ): Object
}

type Object {
    id: ID!
    email: AWSEmail
    json: AWSJSON
    date: AWSDate
    time: AWSTime
    datetime: AWSDateTime
    timestamp: AWSTimestamp
    url: AWSURL
    phoneno: AWSPhone
    ip: AWSIPAddress
}

type Query {
    getObject(id: ID!): Object
    listObjects: [Object]
}

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

Voici à quoi `putObject` pourrait ressembler un modèle de demande. A `putObject` utilise une `PutItem` opération pour créer ou mettre à jour un élément dans votre table Amazon DynamoDB. Notez que cet extrait de code ne contient pas de table Amazon DynamoDB configurée comme source de données. Ceci n'est utilisé qu'à titre d'exemple :

```
{
    "version" : "2017-02-28",
    "operation" : "PutItem",
    "key" : {
        "id": $util.dynamodb.toDynamoDBJson($util.autoId()),
    },
    "attributeValues" : $util.dynamodb.toMapValuesJson($ctx.args)
}
```

Le modèle de réponse pour `putObject` renvoie les résultats :

```
$util.toJson($ctx.result)
```

Voici à quoi `getObject` pourrait ressembler un modèle de demande. A `getObject` utilise une `GetItem` opération pour renvoyer un ensemble d'attributs pour l'élément doté de la clé primaire. Notez que cet extrait de code ne contient pas de table Amazon DynamoDB configurée comme source de données. Ceci n'est utilisé qu'à titre d'exemple :

```
{
    "version": "2017-02-28",
    "operation": "GetItem",
    "key": {
        "id": $util.dynamodb.toDynamoDBJson($ctx.args.id),
    }
}
```

Le modèle de réponse pour `getObject` renvoie les résultats :

```
$util.toJson($ctx.result)
```

Voici à quoi `listObjects` pourrait ressembler un modèle de demande. A `listObjects` utilise une `Scan` opération pour renvoyer un ou plusieurs éléments et attributs. Notez que cet extrait de code ne contient pas de table Amazon DynamoDB configurée comme source de données. Ceci n'est utilisé qu'à titre d'exemple :

```
{
    "version" : "2017-02-28",
    "operation" : "Scan",
}
```

Le modèle de réponse pour `listObjects` renvoie les résultats :

```
$util.toJson($ctx.result.items)
```

Voici quelques exemples d'utilisation de ce schéma avec des requêtes GraphQL :

```
mutation CreateObject {
    putObject(email: "example@example.com"
        json: "{\"a\":1, \"b\":3, \"string\": 234}"
        date: "1970-01-01Z"
        time: "12:00:34."
        datetime: "1930-01-01T16:00:00-07:00"
        timestamp: -123123
        url:"https://amazon.com"
        phoneno: "+1 555 764 4377"
        ip: "127.0.0.1/8"
    ) {
        id
        email
        json
        date
        time
        datetime
        url
        timestamp
        phoneno
        ip
    }
}

query getObject {
    getObject(id:"0d97daf0-48e6-4ffc-8d48-0537e8a843d2"){
        email
        url
        timestamp
        phoneno
        ip
    }
}

query listObjects {
    listObjects {
        json
        date
        time
        datetime
    }
}
```

# Interfaces et unions dans GraphQL
<a name="interfaces-and-unions"></a>

[Le système de type GraphQL prend en charge les interfaces.](https://graphql.org/learn/schema/#interfaces) Une interface expose un certain ensemble de champs qu'un type doit inclure pour implémenter l'interface. 

[Le système de type GraphQL prend également en charge les unions.](https://graphql.org/learn/schema/#union-types) Les unions sont identiques aux interfaces, si ce n'est qu'elles ne définissent pas un ensemble commun de champs. Les unions sont généralement préférées aux interfaces lorsque les types possibles ne partagent pas une hiérarchie logique.

La section suivante est une référence pour la saisie de schémas.

## Exemples d'interface
<a name="interfaces"></a>

Nous pourrions représenter une `Event` interface représentant tout type d'activité ou de rassemblement de personnes. Certains types d'événements possibles sont `Concert``Conference`, et`Festival`. Ces types partagent tous des caractéristiques communes : ils ont tous un nom, un lieu où l'événement se déroule, ainsi qu'une date de début et une date de fin. Ces types présentent également des différences ; un `Conference` propose une liste de conférenciers et d'ateliers, tandis qu'un `Concert` propose un groupe de musique.

Dans le langage SDL (Schema Definition Language), l'`Event`interface est définie comme suit :

```
interface Event {
        id: ID!
        name : String!
        startsAt: String
        endsAt: String
        venue: Venue
        minAgeRestriction: Int
}
```

Et chacun des types implémente l'`Event`interface comme suit :

```
type Concert implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performingBand: String
}

type Festival implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performers: [String]
}

type Conference implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    speakers: [String]
    workshops: [String]
}
```

Les interfaces sont utiles pour représenter des éléments qui peuvent être de plusieurs types. Par exemple, nous pourrions rechercher tous les événements se déroulant dans un lieu spécifique. Ajoutons un champ `findEventsByVenue` au schéma :

```
schema {
    query: Query
}

type Query {
    # Retrieve Events at a specific Venue
    findEventsAtVenue(venueId: ID!): [Event]
}

type Venue {
    id: ID!
    name: String
    address: String
    maxOccupancy: Int
}

type Concert implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performingBand: String
}

interface Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
}

type Festival implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performers: [String]
}

type Conference implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    speakers: [String]
    workshops: [String]
}
```

`findEventsByVenue`Renvoie une liste de`Event`. Comme les champs d'interface GraphQL sont communs à tous les types d'implémentation, il est possible de sélectionner tous les champs de l'interface `Event` (`id`, `name`, `startsAt`, `endsAt`, `venue` et `minAgeRestriction`). En outre, vous pouvez accéder aux champs sur n'importe quel type d'implémentation en utilisant des [fragments](https://graphql.org/learn/queries/#fragments) GraphQL, tant que vous en spécifiez le type.

Examinons un exemple de requête GraphQL utilisant l'interface.

```
query {
  findEventsAtVenue(venueId: "Madison Square Garden") {
    id
    name
    minAgeRestriction
    startsAt

    ... on Festival {
      performers
    }

    ... on Concert {
      performingBand
    }

    ... on Conference {
      speakers
      workshops
    }
  }
}
```

La requête précédente génère une liste unique de résultats et le serveur pourrait, par défaut, trier les événements par date de début.

```
{
  "data": {
    "findEventsAtVenue": [
      {
        "id": "Festival-2",
        "name": "Festival 2",
        "minAgeRestriction": 21,
        "startsAt": "2018-10-05T14:48:00.000Z",
        "performers": [
          "The Singers",
          "The Screamers"
        ]
      },
      {
        "id": "Concert-3",
        "name": "Concert 3",
        "minAgeRestriction": 18,
        "startsAt": "2018-10-07T14:48:00.000Z",
        "performingBand": "The Jumpers"
      },
      {
        "id": "Conference-4",
        "name": "Conference 4",
        "minAgeRestriction": null,
        "startsAt": "2018-10-09T14:48:00.000Z",
        "speakers": [
          "The Storytellers"
        ],
        "workshops": [
          "Writing",
          "Reading"
        ]
      }
    ]
  }
}
```

Les résultats étant renvoyés sous la forme d'un ensemble unique d'événements, l'utilisation d'interfaces pour représenter des caractéristiques communes est très utile pour trier les résultats.

## Exemples syndicaux
<a name="unions"></a>

Comme indiqué précédemment, les syndicats ne définissent pas d'ensembles de domaines communs. Un résultat de recherche peut représenter de nombreux types différents. À l'aide du schéma `Event`, vous pouvez définir une union `SearchResult` comme suit :

```
type Query {
    # Retrieve Events at a specific Venue
    findEventsAtVenue(venueId: ID!): [Event]
    # Search across all content
    search(query: String!): [SearchResult]
}

union SearchResult = Conference | Festival | Concert | Venue
```

Dans ce cas, pour interroger n'importe quel champ de notre `SearchResult` union, vous devez utiliser des fragments :

```
query {
  search(query: "Madison") {
    ... on Venue {
      id
      name
      address
    }

    ... on Festival {
      id
      name
      performers
    }

    ... on Concert {
      id
      name
      performingBand
    }

    ... on Conference {
      speakers
      workshops
    }
  }
}
```

## Tapez la résolution dans AWS AppSync
<a name="type-resolution-in-appsynclong"></a>

La résolution de type est le mécanisme par lequel le moteur GraphQL identifie une valeur résolue en tant que type d'objet spécifique.

Pour en revenir à l'exemple de recherche syndicale, à condition que notre requête produise des résultats, chaque élément de la liste des résultats doit se présenter comme l'un des types possibles définis par l'`SearchResult`union (c'est-à-dire,`Conference`, `Festival``Concert`, ou`Venue`).

Comme la logique permettant d'identifier un événement `Festival` d'un élément `Venue` ou `Conference` dépend des exigences de l'application, le moteur GraphQL doit se voir attribuer un conseil, pour identifier nos types possibles parmi les résultats bruts.

Avec AWS AppSync, cet indice est représenté par un champ méta nommé`__typename`, dont la valeur correspond au nom du type d'objet identifié. `__typename`est obligatoire pour les types de retour qui sont des interfaces ou des unions.

## Exemple de résolution de type
<a name="type-resolution-example"></a>

Réutilisons le schéma précédent. Vous pouvez suivre en accédant à la console et en ajoutant les éléments suivants sous la page **Schéma** :

```
schema {
    query: Query
}

type Query {
    # Retrieve Events at a specific Venue
    findEventsAtVenue(venueId: ID!): [Event]
    # Search across all content
    search(query: String!): [SearchResult]
}

union SearchResult = Conference | Festival | Concert | Venue

type Venue {
    id: ID!
    name: String!
    address: String
    maxOccupancy: Int
}

interface Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
}

type Festival implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performers: [String]
}

type Conference implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    speakers: [String]
    workshops: [String]
}

type Concert implements Event {
    id: ID!
    name: String!
    startsAt: String
    endsAt: String
    venue: Venue
    minAgeRestriction: Int
    performingBand: String
}
```

Attachons un résolveur au champ `Query.search`. Dans la `Resolvers` section, choisissez **Joindre**, créez une nouvelle **source de données** de type *NONE*, puis nommez-la *StubDataSource*. Dans le cadre de cet exemple, nous allons prétendre que nous avons récupéré des résultats d'une source externe, et coder les résultats récupérés dans notre modèle de mappage de requête.

Dans le volet du modèle de mappage de requête, saisissez :

```
{
    "version" : "2018-05-29",
    "payload":
    ## We are effectively mocking our search results for this example
    [
        {
            "id": "Venue-1",
            "name": "Venue 1",
            "address": "2121 7th Ave, Seattle, WA 98121",
            "maxOccupancy": 1000
        },
        {
            "id": "Festival-2",
            "name": "Festival 2",
            "performers": ["The Singers", "The Screamers"]
        },
        {
            "id": "Concert-3",
            "name": "Concert 3",
            "performingBand": "The Jumpers"
        },
        {
            "id": "Conference-4",
            "name": "Conference 4",
            "speakers": ["The Storytellers"],
            "workshops": ["Writing", "Reading"]
        }
    ]
}
```

Si l'application renvoie le nom du type dans le `id` champ, la logique de résolution de type doit analyser le `id` champ pour extraire le nom du type, puis ajouter le `__typename` champ à chacun des résultats. Vous pouvez exécuter cette logique dans le modèle de mappage de réponse comme suit :

**Note**  
Vous pouvez également effectuer cette tâche dans le cadre de votre fonction Lambda, si vous utilisez la source de données Lambda.

```
#foreach ($result in $context.result)
    ## Extract type name from the id field.
    #set( $typeName = $result.id.split("-")[0] )
    #set( $ignore = $result.put("__typename", $typeName))
#end
$util.toJson($context.result)
```

Exécutez la requête suivante :

```
query {
  search(query: "Madison") {
    ... on Venue {
      id
      name
      address
    }

    ... on Festival {
        id
      name
      performers
    }

    ... on Concert {
      id
      name
      performingBand
    }

    ... on Conference {
      speakers
      workshops
    }
  }
}
```

La requête produit les résultats suivants :

```
{
  "data": {
    "search": [
      {
        "id": "Venue-1",
        "name": "Venue 1",
        "address": "2121 7th Ave, Seattle, WA 98121"
      },
      {
        "id": "Festival-2",
        "name": "Festival 2",
        "performers": [
          "The Singers",
          "The Screamers"
        ]
      },
      {
        "id": "Concert-3",
        "name": "Concert 3",
        "performingBand": "The Jumpers"
      },
      {
        "speakers": [
          "The Storytellers"
        ],
        "workshops": [
          "Writing",
          "Reading"
        ]
      }
    ]
  }
}
```

La logique de résolution de type varie en fonction de l'application. Par exemple, vous pouvez avoir une logique d'identification différente qui recherche l'existence de certains champs ou même une combinaison de champs. En d'autres termes, vous pourriez détecter la présence du champ `performers` pour identifier un événement `Festival` ou la combinaison des champs `speakers` et `workshops` pour identifier un événement `Conference`. En fin de compte, c'est à vous de définir la logique que vous souhaitez utiliser.