

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.

# Création d'une post-application simple à l'aide des résolveurs DynamoDB
<a name="tutorial-dynamodb-resolvers"></a>

**Note**  
Nous prenons désormais principalement en charge le runtime APPSYNC\$1JS et sa documentation. [Pensez à utiliser le runtime APPSYNC\$1JS et ses guides ici.](https://docs.aws.amazon.com/appsync/latest/devguide/tutorials-js.html)

Ce didacticiel explique comment importer vos propres tables Amazon DynamoDB et les connecter AWS AppSync à une API GraphQL.

Vous pouvez autoriser le AWS AppSync provisionnement des ressources DynamoDB en votre nom. Ou, si vous préférez, vous pouvez connecter vos tables existantes à un schéma GraphQL en créant une source de données et un résolveur. Dans les deux cas, vous serez en mesure de lire et d'écrire dans votre base de données DynamoDB via les instructions GraphQL, et de vous abonner aux données en temps réel.

Certaines étapes de configuration spécifiques doivent être effectuées pour convertir des instructions GraphQL en opérations DynamoDB, et pour reconvertir les réponses dans GraphQL. Ce didacticiel explique le processus de configuration par le biais de plusieurs scénarios et modèles d'accès aux données concrets.

## Configuration de vos tables DynamoDB
<a name="setting-up-your-ddb-tables"></a>

Pour commencer ce didacticiel, vous devez d'abord suivre les étapes ci-dessous pour provisionner AWS les ressources.

1. Provisionnez les AWS ressources à l'aide du AWS CloudFormation modèle suivant dans la CLI :

   ```
   aws cloudformation create-stack \
       --stack-name AWSAppSyncTutorialForAmazonDynamoDB \
       --template-url https://s3.us-west-2.amazonaws.com/awsappsync/resources/dynamodb/AmazonDynamoDBCFTemplate.yaml \
       --capabilities CAPABILITY_NAMED_IAM
   ```

   Vous pouvez également lancer la CloudFormation pile suivante dans la région US-West 2 (Oregon) sur votre AWS compte.

   [https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/dynamodb/AmazonDynamoDBCFTemplate.yaml](https://console.aws.amazon.com/cloudformation/home?region=us-west-2#/stacks/new?templateURL=https://s3.us-west-2.amazonaws.com/awsappsync/resources/dynamodb/AmazonDynamoDBCFTemplate.yaml)

   Cela crée les éléments suivants :
   + Une table DynamoDB `AppSyncTutorial-Post` appelée qui contiendra les données. `Post`
   + Un rôle IAM et une politique gérée IAM associée permettant d' AWS AppSync interagir avec la `Post` table.

1. Pour plus de détails sur la pile et les ressources créées, exécutez la commande d'interface de ligne de commande suivante :

   ```
   aws cloudformation describe-stacks --stack-name AWSAppSyncTutorialForAmazonDynamoDB
   ```

1. Pour supprimer ultérieurement les ressources, vous pouvez exécuter :

   ```
   aws cloudformation delete-stack --stack-name AWSAppSyncTutorialForAmazonDynamoDB
   ```

## Création de votre API GraphQL
<a name="creating-your-graphql-api"></a>

Pour créer l'API GraphQL dans : AWS AppSync

1. Connectez-vous à la [AppSync console AWS Management Console et ouvrez-la](https://console.aws.amazon.com/appsync/).

   1. Dans le **APIs tableau de bord**, choisissez **Create API**.

1. Dans la fenêtre **Personnaliser votre API ou importer depuis Amazon DynamoDB**, **choisissez** Créer à partir de zéro.

   1. Choisissez **Démarrer** à droite de la même fenêtre.

1. Dans le champ **Nom de l'API**, définissez le nom de l'API sur`AWSAppSyncTutorial`.

1. Choisissez **Créer**.

La AWS AppSync console crée une nouvelle API GraphQL pour vous en utilisant le mode d'authentification par clé d'API. Vous pouvez utiliser la console pour configurer le reste de l'API GraphQL et exécuter des requêtes sur celle-ci jusqu'à la fin de ce didacticiel.

## Définition d'une API de publication de base
<a name="defining-a-basic-post-api"></a>

Maintenant que vous avez créé une API AWS AppSync GraphQL, vous pouvez configurer un schéma de base qui permet la création, la récupération et la suppression de base des données de publication.

1. Connectez-vous à la [AppSync console AWS Management Console et ouvrez-la](https://console.aws.amazon.com/appsync/).

   1. Dans le **APIs tableau de bord**, choisissez l'API que vous venez de créer.

1. Dans la **barre latérale**, choisissez **Schema.**

   1. Dans le volet **Schéma**, remplacez le contenu par le code suivant :

     ```
     schema {
         query: Query
         mutation: Mutation
     }
     
     type Query {
         getPost(id: ID): Post
     }
     
     type Mutation {
         addPost(
             id: ID!
             author: String!
             title: String!
             content: String!
             url: String!
         ): Post!
     }
     
     type Post {
         id: ID!
         author: String
         title: String
         content: String
         url: String
         ups: Int!
         downs: Int!
         version: Int!
     }
     ```

1. Choisissez **Enregistrer**.

Ce schéma définit un type `Post` et des opérations pour ajouter et obtenir des objets `Post`.

## Configuration de la source de données pour les tables DynamoDB
<a name="configuring-the-data-source-for-the-ddb-tables"></a>

Liez ensuite les requêtes et les mutations définies dans le schéma à la table `AppSyncTutorial-Post` DynamoDB.

Tout d' AWS AppSync abord, vous devez connaître vos tables. Pour ce faire, vous devez configurer une source de données dans AWS AppSync :

1. Connectez-vous à la [AppSync console AWS Management Console et ouvrez-la](https://console.aws.amazon.com/appsync/).

   1. Dans le **APIs tableau de bord**, choisissez votre API GraphQL.

   1. Dans la **barre latérale**, sélectionnez **Sources de données.**

1. Choisissez **Create data source**.

   1. Dans le **champ Nom de la source de données**, entrez`PostDynamoDBTable`. 

   1. Pour le **type de source de données**, choisissez la **table Amazon DynamoDB**.

   1. Pour **Région**, choisissez **US-WEST-2**.

   1. Pour **Nom de la table**, choisissez la table **AppSyncTutorialDynamoDB -Post**.

   1. Créez un nouveau rôle IAM (recommandé) ou choisissez un rôle existant disposant de l'autorisation `lambda:invokeFunction` IAM. Les rôles existants nécessitent une politique de confiance, comme expliqué dans la section [Joindre une source de données](attaching-a-data-source.md). 

      Voici un exemple de politique IAM disposant des autorisations requises pour effectuer des opérations sur la ressource :

------
#### [ JSON ]

****  

      ```
      { 
           "Version":"2012-10-17",		 	 	  
           "Statement": [ 
               { 
                   "Effect": "Allow", 
                   "Action": [ "lambda:invokeFunction" ], 
                   "Resource": [ 
                       "arn:aws:lambda:us-east-1:111122223333:function:myFunction", 
                       "arn:aws:lambda:us-east-1:111122223333:function:myFunction:*" 
                   ] 
               } 
           ] 
       }
      ```

------

1. Choisissez **Créer**.

## Configuration du résolveur AddPost (DynamoDB) PutItem
<a name="setting-up-the-addpost-resolver-dynamodb-putitem"></a>

**Une fois AWS AppSync que vous avez pris connaissance de la table DynamoDB, vous pouvez la lier à des requêtes et à des mutations individuelles en définissant des résolveurs.** Le premier résolveur que vous créez est le `addPost` résolveur, qui vous permet de créer une publication dans la table DynamoDB`AppSyncTutorial-Post`.

Un résolveur comprend les éléments suivants :
+ L'emplacement dans le schéma GraphQL pour joindre le résolveur. Dans ce cas, vous configurez un résolveur sur le champ `addPost` sur le type `Mutation`. Ce résolveur est appelé lorsque l'appelant appelle `mutation { addPost(...){...} }`.
+ La source de données à utiliser pour ce résolveur. Dans ce cas, vous souhaitez utiliser la source de données `PostDynamoDBTable` que vous avez définie précédemment, afin de pouvoir ajouter des entrées dans la table DynamoDB `AppSyncTutorial-Post`.
+ Le modèle de mappage de demande. L'objectif du modèle de mappage des demandes est de prendre la demande entrante de l'appelant et de la traduire en instructions AWS AppSync à exécuter par rapport à DynamoDB.
+ Le modèle de mappage de réponse. La tâche du modèle de mappage de réponse est de prendre la réponse provenant de DynamoDB et de la reconvertir en quelque chose que GraphQL attend. Cela est utile si la forme des données dans DynamoDB est différente du type `Post` dans GraphQL, mais dans ce cas, ils ont la même forme, de sorte que vous transmettez simplement les données.

Pour configurer le résolveur :

1. Connectez-vous à la [AppSync console AWS Management Console et ouvrez-la](https://console.aws.amazon.com/appsync/).

   1. Dans le **APIs tableau de bord**, choisissez votre API GraphQL.

   1. Dans la **barre latérale**, sélectionnez **Sources de données.**

1. Choisissez **Create data source**.

   1. Dans le **champ Nom de la source de données**, entrez`PostDynamoDBTable`. 

   1. Pour le **type de source de données**, choisissez la **table Amazon DynamoDB**.

   1. Pour **Région**, choisissez **US-WEST-2**.

   1. Pour **Nom de la table**, choisissez la table **AppSyncTutorialDynamoDB -Post**.

   1. Créez un nouveau rôle IAM (recommandé) ou choisissez un rôle existant disposant de l'autorisation `lambda:invokeFunction` IAM. Les rôles existants nécessitent une politique de confiance, comme expliqué dans la section [Joindre une source de données](attaching-a-data-source.md). 

      Voici un exemple de politique IAM disposant des autorisations requises pour effectuer des opérations sur la ressource :

------
#### [ JSON ]

****  

      ```
      { 
           "Version":"2012-10-17",		 	 	  
           "Statement": [ 
               { 
                   "Effect": "Allow", 
                   "Action": [ "lambda:invokeFunction" ], 
                   "Resource": [ 
                       "arn:aws:lambda:us-west-2:123456789012:function:myFunction", 
                       "arn:aws:lambda:us-west-2:123456789012:function:myFunction:*" 
                   ] 
               } 
           ] 
       }
      ```

------

1. Choisissez **Créer**.

1. Choisissez l'onglet **Schéma**.

1. Dans le volet **Types de données** sur la droite, se trouve le champ **addPost** sur le type **Mutation**, choisissez ensuite **Joindre**.

1. Dans le **menu Action**, choisissez **Update runtime**, puis **Unit Resolver (VTL uniquement**).

1. Dans **Nom de la source de données**, choisissez **PostDynamoDBTable**.

1. Collez ce qui suit dans la section **Configurer le modèle de mappage de demande** :

   ```
   {
       "version" : "2017-02-28",
       "operation" : "PutItem",
       "key" : {
           "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
       },
       "attributeValues" : {
           "author" : $util.dynamodb.toDynamoDBJson($context.arguments.author),
           "title" : $util.dynamodb.toDynamoDBJson($context.arguments.title),
           "content" : $util.dynamodb.toDynamoDBJson($context.arguments.content),
           "url" : $util.dynamodb.toDynamoDBJson($context.arguments.url),
           "ups" : { "N" : 1 },
           "downs" : { "N" : 0 },
           "version" : { "N" : 1 }
       }
   }
   ```

   **Remarque :** un *type* est spécifié sur toutes les clés et valeurs d'attribut. Par exemple, vous définissez le champ `author` sur `{ "S" : "${context.arguments.author}" }`. La `S` partie indique à DynamoDB AWS AppSync et à DynamoDB que la valeur sera une valeur de chaîne. La valeur réelle est renseignée à partir de l'argument `author`. De la même façon, le champ `version` est un champ numérique, car il utilise `N` comme type. Enfin, vous initialisez également les champs `ups`, `downs` et `version`.

   Pour ce didacticiel, vous avez indiqué que le `ID!` type GraphQL, qui indexe le nouvel élément inséré dans DynamoDB, fait partie des arguments du client. AWS AppSync est livré avec un utilitaire de génération automatique d'identifiants appelé `$utils.autoId()` que vous auriez également pu utiliser sous la forme de`"id" : { "S" : "${$utils.autoId()}" }`. Ensuite, vous pourriez simplement laisser `id: ID!` hors de la définition de schéma de `addPost()` et il serait inséré automatiquement. Vous n'utiliserez pas cette technique dans ce didacticiel, mais vous devez la considérer comme une bonne pratique lorsque vous écrivez dans des tables DynamoDB.

   Pour plus d'informations sur les modèles de mappage, consultez la documentation de référence [Présentation des modèles de mappage des résolveurs](resolver-mapping-template-reference-overview.md#aws-appsync-resolver-mapping-template-reference-overview). Pour plus d'informations sur le mappage des GetItem demandes, consultez la documentation de [GetItem](aws-appsync-resolver-mapping-template-reference-dynamodb-getitem.md)référence. Pour plus d'informations sur les types, consultez la documentation de référence [Système de types (mappage de demande)](aws-appsync-resolver-mapping-template-reference-dynamodb-typed-values-request.md).

1. Collez ce qui suit dans la section **Configurer le modèle de mappage de réponse** :

   ```
   $utils.toJson($context.result)
   ```

    **Remarque :** comme la forme des données de la table `AppSyncTutorial-Post` correspond exactement à la forme du type `Post` dans GraphQL, le modèle de mappage de réponse transmet simplement directement les résultats. Notez également que tous les exemples utilisés dans ce tutoriel utilisent le même modèle de mappage de réponse, si bien que vous ne créez qu'un fichier.

1. Choisissez **Enregistrer**.

### Appel de l'API pour ajouter une publication
<a name="call-the-api-to-add-a-post"></a>

Maintenant que le résolveur est configuré, il AWS AppSync peut traduire une `addPost` mutation entrante en une opération DynamoDB PutItem . Vous pouvez désormais exécuter une mutation pour placer quelque chose dans la table.
+ Choisissez l'onglet **Requêtes**.
+ Collez la mutation suivante dans le volet **Requêtes**.

  ```
  mutation addPost {
    addPost(
      id: 123
      author: "AUTHORNAME"
      title: "Our first post!"
      content: "This is our first post."
      url: "https://aws.amazon.com/appsync/"
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ Les résultats de la publication nouvellement créée doivent apparaître dans le volet des résultats à droite du volet de requête. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "addPost": {
        "id": "123",
        "author": "AUTHORNAME",
        "title": "Our first post!",
        "content": "This is our first post.",
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 1
      }
    }
  }
  ```

Voici ce qui s'est produit :
+ AWS AppSync a reçu une demande de `addPost` mutation.
+ AWS AppSync a pris la demande et le modèle de mappage des demandes, et a généré un document de mappage des demandes. Celui-ci se présentait comme suit :

  ```
  {
      "version" : "2017-02-28",
      "operation" : "PutItem",
      "key" : {
          "id" : { "S" : "123" }
      },
      "attributeValues" : {
          "author": { "S" : "AUTHORNAME" },
          "title": { "S" : "Our first post!" },
          "content": { "S" : "This is our first post." },
          "url": { "S" : "https://aws.amazon.com/appsync/" },
          "ups" : { "N" : 1 },
          "downs" : { "N" : 0 },
          "version" : { "N" : 1 }
      }
  }
  ```
+ AWS AppSync a utilisé le document de mappage des demandes pour générer et exécuter une demande `PutItem` DynamoDB.
+ AWS AppSync a pris les résultats de la `PutItem` requête et les a reconvertis en types GraphQL.

  ```
  {
      "id" : "123",
      "author": "AUTHORNAME",
      "title": "Our first post!",
      "content": "This is our first post.",
      "url": "https://aws.amazon.com/appsync/",
      "ups" : 1,
      "downs" : 0,
      "version" : 1
  }
  ```
+ Ils ont été transmis via le document de mappage de réponse, qui les a transmis sans les changer.
+ L'objet nouvellement créé a été renvoyé dans la réponse GraphQL.

## Configuration du résolveur GetPost (DynamoDB) GetItem
<a name="setting-up-the-getpost-resolver-ddb-getitem"></a>

Maintenant que vous pouvez ajouter des données à la table `AppSyncTutorial-Post` DynamoDB, vous devez configurer `getPost` la requête afin qu'elle puisse récupérer ces données de la table. `AppSyncTutorial-Post` Pour ce faire, vous configurez un autre résolveur.
+ Choisissez l'onglet **Schéma**.
+ Dans le volet **Types de données** sur la droite, cherchez le champ **getPost** sur le type **Requête**, puis choisissez **Joindre**.
+ Dans le **menu Action**, choisissez **Update runtime**, puis **Unit Resolver (VTL uniquement**).
+ Dans **Nom de la source de données**, choisissez **PostDynamoDBTable**.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de demande** :

  ```
  {
      "version" : "2017-02-28",
      "operation" : "GetItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
      }
  }
  ```
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de réponse** :

  ```
  $utils.toJson($context.result)
  ```
+ Choisissez **Enregistrer**.

### Appel de l'API pour obtenir une publication
<a name="call-the-api-to-get-a-post"></a>

Maintenant que le résolveur est configuré, AWS AppSync il sait comment traduire une `getPost` requête entrante en une opération DynamoDB`GetItem`. Vous pouvez désormais exécuter une requête pour récupérer la publication que vous avez créée précédemment.
+ Choisissez l'onglet **Requêtes**.
+ Collez ce qui suit dans le volet **Requêtes** :

  ```
  query getPost {
    getPost(id:123) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ La publication extraite de DynamoDB doit apparaître dans le volet des résultats à droite du volet des requêtes. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "getPost": {
        "id": "123",
        "author": "AUTHORNAME",
        "title": "Our first post!",
        "content": "This is our first post.",
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 1
      }
    }
  }
  ```

Voici ce qui s'est produit :
+ AWS AppSync a reçu une demande de `getPost` requête.
+ AWS AppSync a pris la demande et le modèle de mappage des demandes, et a généré un document de mappage des demandes. Celui-ci se présentait comme suit :

  ```
  {
      "version" : "2017-02-28",
      "operation" : "GetItem",
      "key" : {
          "id" : { "S" : "123" }
      }
  }
  ```
+ AWS AppSync a utilisé le document de mappage des demandes pour générer et exécuter une demande GetItem DynamoDB.
+ AWS AppSync a pris les résultats de la `GetItem` requête et les a reconvertis en types GraphQL.

  ```
  {
      "id" : "123",
      "author": "AUTHORNAME",
      "title": "Our first post!",
      "content": "This is our first post.",
      "url": "https://aws.amazon.com/appsync/",
      "ups" : 1,
      "downs" : 0,
      "version" : 1
  }
  ```
+ Ils ont été transmis via le document de mappage de réponse, qui les a transmis sans les changer.
+ L'objet récupéré a été renvoyé dans la réponse.

Vous pouvez également prendre l'exemple suivant :

```
query getPost {
  getPost(id:123) {
    id
    author
    title
  }
}
```

Si votre `getPost` requête n'a besoin que du`id`, et `author``title`, vous pouvez modifier votre modèle de mappage de demandes pour utiliser des expressions de projection afin de spécifier uniquement les attributs que vous souhaitez voir apparaître dans votre table DynamoDB afin d'éviter tout transfert de données inutile de DynamoDB vers. AWS AppSync Par exemple, le modèle de mappage des demandes peut ressembler à l'extrait ci-dessous :

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

## Création d'une mutation UpdatePost (DynamoDB) UpdateItem
<a name="create-an-updatepost-mutation-ddb-updateitem"></a>

Jusqu'à présent, vous pouvez créer et récupérer `Post` des objets dans DynamoDB. Ensuite, vous allez configurer une nouvelle mutation pour pouvoir mettre à jour l'objet. Pour ce faire, utilisez l'opération UpdateItem DynamoDB.
+ Choisissez l'onglet **Schéma**.
+ Dans le volet **Schéma**, modifiez le type `Mutation` pour ajouter une nouvelle mutation `updatePost` :

  ```
  type Mutation {
      updatePost(
          id: ID!,
          author: String!,
          title: String!,
          content: String!,
          url: String!
      ): Post
      addPost(
          author: String!
          title: String!
          content: String!
          url: String!
      ): Post!
  }
  ```
+ Choisissez **Enregistrer**.
+ Dans le volet **Types de données** sur la droite, se trouve le champ **updatePost** qui vient d'être créé, sur le type **Mutation**, choisissez ensuite **Joindre**.
+ Dans le **menu Action**, choisissez **Update runtime**, puis **Unit Resolver (VTL uniquement**).
+ Dans **Nom de la source de données**, choisissez **PostDynamoDBTable**.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de demande** :

  ```
  {
      "version" : "2017-02-28",
      "operation" : "UpdateItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
      },
      "update" : {
          "expression" : "SET author = :author, title = :title, content = :content, #url = :url ADD version :one",
          "expressionNames": {
              "#url" : "url"
          },
          "expressionValues": {
              ":author" : $util.dynamodb.toDynamoDBJson($context.arguments.author),
              ":title" : $util.dynamodb.toDynamoDBJson($context.arguments.title),
              ":content" : $util.dynamodb.toDynamoDBJson($context.arguments.content),
              ":url" : $util.dynamodb.toDynamoDBJson($context.arguments.url),
              ":one" : { "N": 1 }
          }
      }
  }
  ```

   **Remarque :** Ce résolveur utilise le UpdateItem DynamoDB, qui est très différent de l'opération. PutItem Au lieu d'écrire l'élément dans son intégralité, vous demandez simplement à DynamoDB de mettre à jour certains attributs. Cela se fait à l'aide des expressions de mise à jour DynamoDB. L'expression elle-même est spécifiée dans le champ `expression` de la section `update`. Elle indique de définir les attributs `author`, `title`, `content` et URL, puis d'incrémenter le champ `version`. Les valeurs à utiliser n'apparaissent pas dans l'expression elle-même ; l'expression a des espaces réservés qui ont des noms qui commencent par deux points et qui sont ensuite définis dans le champ `expressionValues`. Enfin, DynamoDB a réservé des mots qui ne peuvent pas apparaître dans le. `expression` Par exemple, `url` est un mot réservé, si bien que pour mettre à jour le champ `url`, vous pouvez utiliser des espaces réservés de nom et les définir dans le champ `expressionNames`.

  Pour plus d'informations sur le mappage des `UpdateItem` demandes, consultez la documentation de [UpdateItem](aws-appsync-resolver-mapping-template-reference-dynamodb-updateitem.md)référence. Pour plus d'informations sur l'écriture d'expressions de mise à jour, consultez la documentation [ UpdateExpressions DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html).
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de réponse** :

  ```
  $utils.toJson($context.result)
  ```

### Appel de l'API pour mettre à jour une publication
<a name="call-the-api-to-update-a-post"></a>

Maintenant que le résolveur est configuré, AWS AppSync il sait comment traduire une `update` mutation entrante en une opération DynamoDB`Update`. Vous pouvez désormais exécuter une mutation pour mettre à jour l'élément que vous avez écrit précédemment.
+ Choisissez l'onglet **Requêtes**.
+ Collez la mutation suivante dans le volet **Requêtes**. Vous devrez également mettre à jour l'argument `id` pour qu'il ait la valeur que vous avez notée précédemment.

  ```
  mutation updatePost {
    updatePost(
      id:"123"
      author: "A new author"
      title: "An updated author!"
      content: "Now with updated content!"
      url: "https://aws.amazon.com/appsync/"
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ La publication mise à jour dans DynamoDB doit apparaître dans le volet des résultats à droite du volet des requêtes. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "updatePost": {
        "id": "123",
        "author": "A new author",
        "title": "An updated author!",
        "content": "Now with updated content!",
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 2
      }
    }
  }
  ```

Dans cet exemple, les `downs` champs `ups` et n'ont pas été modifiés car le modèle de mappage des demandes n'a pas demandé à AWS AppSync DynamoDB de faire quoi que ce soit avec ces champs. De plus, le `version` champ a été incrémenté de 1 parce que vous avez demandé AWS AppSync à DynamoDB d'ajouter 1 au champ. `version`

## Modification du résolveur UpdatePost (DynamoDB) UpdateItem
<a name="modifying-the-updatepost-resolver-dynamodb-updateitem"></a>

Il s'agit d'un bon début pour la mutation `updatePost`, mais elle comporte deux problèmes principaux :
+ Si vous souhaitez mettre à jour un seul champ, vous devez mettre à jour tous les champs.
+ Si deux personnes modifient l'objet, des informations risquent d'être perdues.

Pour résoudre ces problèmes, vous allez modifier la mutation `updatePost` pour modifier uniquement les arguments qui ont été spécifiés dans la demande, puis ajouter une condition à l'opération `UpdateItem`.

1. Choisissez l'onglet **Schéma**.

1. Dans le volet **Schéma**, modifiez le champ `updatePost` dans le type `Mutation` pour supprimer les points d'exclamation des arguments `author`, `title`, `content`, et `url`, en veillant à laisser le champ `id` en l'état. Cela rend ces arguments facultatifs. En outre, ajoutez un nouvel argument `expectedVersion` requis.

   ```
   type Mutation {
       updatePost(
           id: ID!,
           author: String,
           title: String,
           content: String,
           url: String,
           expectedVersion: Int!
       ): Post
       addPost(
           author: String!
           title: String!
           content: String!
           url: String!
       ): Post!
   }
   ```

1. Choisissez **Enregistrer**.

1. Dans le volet **Types de données** de droite, cherchez le champ **updatePost** sur le type **Mutation**.

1. Choisissez **PostDynamoDBTable**d'ouvrir le résolveur existant.

1. Modifiez le modèle de mappage de demande dans la section **Configurer le modèle de mappage de demande** :

   ```
   {
       "version" : "2017-02-28",
       "operation" : "UpdateItem",
       "key" : {
           "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
       },
   
       ## Set up some space to keep track of things you're updating **
       #set( $expNames  = {} )
       #set( $expValues = {} )
       #set( $expSet = {} )
       #set( $expAdd = {} )
       #set( $expRemove = [] )
   
       ## Increment "version" by 1 **
       $!{expAdd.put("version", ":one")}
       $!{expValues.put(":one", { "N" : 1 })}
   
       ## Iterate through each argument, skipping "id" and "expectedVersion" **
       #foreach( $entry in $context.arguments.entrySet() )
           #if( $entry.key != "id" && $entry.key != "expectedVersion" )
               #if( (!$entry.value) && ("$!{entry.value}" == "") )
                   ## If the argument is set to "null", then remove that attribute from the item in DynamoDB **
   
                   #set( $discard = ${expRemove.add("#${entry.key}")} )
                   $!{expNames.put("#${entry.key}", "$entry.key")}
               #else
                   ## Otherwise set (or update) the attribute on the item in DynamoDB **
   
                   $!{expSet.put("#${entry.key}", ":${entry.key}")}
                   $!{expNames.put("#${entry.key}", "$entry.key")}
                   $!{expValues.put(":${entry.key}", { "S" : "${entry.value}" })}
               #end
           #end
       #end
   
       ## Start building the update expression, starting with attributes you're going to SET **
       #set( $expression = "" )
       #if( !${expSet.isEmpty()} )
           #set( $expression = "SET" )
           #foreach( $entry in $expSet.entrySet() )
               #set( $expression = "${expression} ${entry.key} = ${entry.value}" )
               #if ( $foreach.hasNext )
                   #set( $expression = "${expression}," )
               #end
           #end
       #end
   
       ## Continue building the update expression, adding attributes you're going to ADD **
       #if( !${expAdd.isEmpty()} )
           #set( $expression = "${expression} ADD" )
           #foreach( $entry in $expAdd.entrySet() )
               #set( $expression = "${expression} ${entry.key} ${entry.value}" )
               #if ( $foreach.hasNext )
                   #set( $expression = "${expression}," )
               #end
           #end
       #end
   
       ## Continue building the update expression, adding attributes you're going to REMOVE **
       #if( !${expRemove.isEmpty()} )
           #set( $expression = "${expression} REMOVE" )
   
           #foreach( $entry in $expRemove )
               #set( $expression = "${expression} ${entry}" )
               #if ( $foreach.hasNext )
                   #set( $expression = "${expression}," )
               #end
           #end
       #end
   
       ## Finally, write the update expression into the document, along with any expressionNames and expressionValues **
       "update" : {
           "expression" : "${expression}"
           #if( !${expNames.isEmpty()} )
               ,"expressionNames" : $utils.toJson($expNames)
           #end
           #if( !${expValues.isEmpty()} )
               ,"expressionValues" : $utils.toJson($expValues)
           #end
       },
   
       "condition" : {
           "expression"       : "version = :expectedVersion",
           "expressionValues" : {
               ":expectedVersion" : $util.dynamodb.toDynamoDBJson($context.arguments.expectedVersion)
           }
       }
   }
   ```

1. Choisissez **Enregistrer**.

Ce modèle est l'un des exemples les plus complexes. Il illustre la puissance et la flexibilité des modèles de mappage. Il passe en revue tous les arguments, en faisant l'impasse sur `id` et `expectedVersion`. Si l'argument est défini sur quelque chose, il demande AWS AppSync à DynamoDB de mettre à jour cet attribut sur l'objet dans DynamoDB. Si l'attribut est défini sur null, il demande AWS AppSync à DynamoDB de le supprimer de l'objet de publication. Si un argument n'a pas été spécifié, il laisse l'attribut. Il incrémente également le champ `version`.

Il existe également une nouvelle section `condition`. Une expression de condition vous permet de dire AWS AppSync à DynamoDB si la demande doit aboutir ou non en fonction de l'état de l'objet déjà présent dans DynamoDB avant l'exécution de l'opération. Dans ce cas, vous souhaitez que la `UpdateItem` demande aboutisse uniquement si le `version` champ de l'élément actuellement dans DynamoDB correspond exactement à l'argument. `expectedVersion`

Pour plus d'informations sur les expressions de condition, consultez la documentation de référence [Expressions de condition](aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions.md).

### Appel de l'API pour mettre à jour une publication
<a name="id1"></a>

Essayons de mettre à jour l'objet `Post` avec le nouveau résolveur :
+ Choisissez l'onglet **Requêtes**.
+ Collez la mutation suivante dans le volet **Requêtes**. Vous devrez également mettre à jour l'argument `id` pour qu'il ait la valeur que vous avez notée précédemment.

  ```
  mutation updatePost {
    updatePost(
      id:123
      title: "An empty story"
      content: null
      expectedVersion: 2
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ La publication mise à jour dans DynamoDB doit apparaître dans le volet des résultats à droite du volet des requêtes. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "updatePost": {
        "id": "123",
        "author": "A new author",
        "title": "An empty story",
        "content": null,
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 3
      }
    }
  }
  ```

Dans cette demande, vous avez demandé à DynamoDB de mettre à jour `title` le `content` champ AWS AppSync et uniquement. Cela a laissé seuls tous les autres champs (autres que l'incrémentation du champ `version`). Vous avez défini l'attribut `title` sur une nouvelle valeur et avons supprimé l'attribut `content` de la publication. Les champs `author`, `url`, `ups` et `downs` sont restés inchangés.

Essayez d'exécuter une nouvelle fois la demande de mutation en laissant la demande exactement telle quelle. La réponse devrait être similaire à ce qui suit :

```
{
  "data": {
    "updatePost": null
  },
  "errors": [
    {
      "path": [
        "updatePost"
      ],
      "data": {
        "id": "123",
        "author": "A new author",
        "title": "An empty story",
        "content": null,
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 3
      },
      "errorType": "DynamoDB:ConditionalCheckFailedException",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)"
    }
  ]
}
```

La demande échoue, car l'expression de condition prend la valeur false :
+ La première fois que vous avez exécuté la demande, la valeur du `version` champ de la publication dans DynamoDB `2` était, qui correspondait à l'argument. `expectedVersion` La demande a abouti, ce qui signifie que le `version` champ a été incrémenté dans DynamoDB à. `3`
+ La deuxième fois que vous avez exécuté la demande, la valeur du `version` champ de la publication dans DynamoDB `3` était, ce qui ne correspondait pas à l'argument. `expectedVersion`

Ce modèle est généralement appelé *Verrouillage optimiste*.

L'une des fonctionnalités d'un résolveur AWS AppSync DynamoDB est qu'il renvoie la valeur actuelle de l'objet de publication dans DynamoDB. Vous pouvez trouver cette valeur dans le champ `data` de la section `errors` de la réponse GraphQL. Votre application peut utiliser ces informations pour déterminer la façon dont elle doit continuer. Dans ce cas, vous pouvez voir que le `version` champ de l'objet dans DynamoDB est défini sur. Vous pouvez donc simplement mettre `3` à jour `expectedVersion` l'argument `3` pour que la demande aboutisse à nouveau.

Consultez la documentation de référence sur le modèle de mappage [Expressions de condition](aws-appsync-resolver-mapping-template-reference-dynamodb-condition-expressions.md) pour obtenir plus d'informations sur la gestion des échecs de vérification de condition.

## Création de mutations UpVotePost et DownVotePost (DynamoDB) UpdateItem
<a name="create-upvotepost-and-downvotepost-mutations-ddb-updateitem"></a>

Le type `Post` a des champs `ups` et `downs` pour permettre d'enregistrer les votes pour et contre, mais jusqu'à présent l'API ne nous laisse rien faire avec eux. Permet d'ajouter certaines mutations pour nous laisser voter pour ou contre les publications.
+ Choisissez l'onglet **Schéma**.
+ Dans le volet **Schéma**, modifiez le type `Mutation` pour ajouter de nouvelles mutations `upvotePost` et `downvotePost` :

  ```
  type Mutation {
      upvotePost(id: ID!): Post
      downvotePost(id: ID!): Post
      updatePost(
          id: ID!,
          author: String,
          title: String,
          content: String,
          url: String,
          expectedVersion: Int!
      ): Post
      addPost(
          author: String!,
          title: String!,
          content: String!,
          url: String!
      ): Post!
  }
  ```
+ Choisissez **Enregistrer**.
+ Dans le volet **Types de données** sur la droite, se trouve le champ **upvotePost** qui vient d'être créé, sur le type **Mutation**, choisissez ensuite **Joindre**.
+ Dans le **menu Action**, choisissez **Update runtime**, puis **Unit Resolver (VTL uniquement**).
+ Dans **Nom de la source de données**, choisissez **PostDynamoDBTable**.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de demande** :

  ```
  {
      "version" : "2017-02-28",
      "operation" : "UpdateItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
      },
      "update" : {
          "expression" : "ADD ups :plusOne, version :plusOne",
          "expressionValues" : {
              ":plusOne" : { "N" : 1 }
          }
      }
  }
  ```
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de réponse** :

  ```
  $utils.toJson($context.result)
  ```
+ Choisissez **Enregistrer**.
+ Dans le volet **Types de données** sur la droite, se trouve le champ `downvotePost` qui vient d'être créé, sur le type **Mutation**, choisissez ensuite **Joindre**.
+ Dans **Nom de la source de données**, choisissez **PostDynamoDBTable**.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de demande** :

  ```
  {
      "version" : "2017-02-28",
      "operation" : "UpdateItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
      },
      "update" : {
          "expression" : "ADD downs :plusOne, version :plusOne",
          "expressionValues" : {
              ":plusOne" : { "N" : 1 }
          }
      }
  }
  ```
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de réponse** :

  ```
  $utils.toJson($context.result)
  ```
+ Choisissez **Enregistrer**.

### Appel de l'API pour voter pour ou contre une publication
<a name="call-the-api-to-upvote-and-downvote-a-post"></a>

Maintenant que les nouveaux résolveurs ont été configurés, ils AWS AppSync savent comment traduire une opération entrante `upvotePost` ou une `downvote` mutation en opération DynamoDB UpdateItem . Vous pouvez désormais exécuter des mutations pour voter pour ou contre la publication que vous avez créée précédemment.
+ Choisissez l'onglet **Requêtes**.
+ Collez la mutation suivante dans le volet **Requêtes**. Vous devrez également mettre à jour l'argument `id` pour qu'il ait la valeur que vous avez notée précédemment.

  ```
  mutation votePost {
    upvotePost(id:123) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ La publication est mise à jour dans DynamoDB et doit apparaître dans le volet des résultats à droite du volet des requêtes. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "upvotePost": {
        "id": "123",
        "author": "A new author",
        "title": "An empty story",
        "content": null,
        "url": "https://aws.amazon.com/appsync/",
        "ups": 6,
        "downs": 0,
        "version": 4
      }
    }
  }
  ```
+ Choisissez **Exécuter une requête** quelque fois de plus. Vous devez voir le champ `ups` et `version` être incrémenté de 1 chaque fois que vous exécutez la requête.
+ Modifiez la requête pour appeler la mutation `downvotePost` :

  ```
  mutation votePost {
    downvotePost(id:123) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange). Cette fois, vous devez voir le champ `downs` et `version` être incrémenté de 1 chaque fois que vous exécutez la requête.

  ```
  {
    "data": {
      "downvotePost": {
        "id": "123",
        "author": "A new author",
        "title": "An empty story",
        "content": null,
        "url": "https://aws.amazon.com/appsync/",
        "ups": 6,
        "downs": 4,
        "version": 12
      }
    }
  }
  ```

## Configuration du résolveur DeletePost (DynamoDB) DeleteItem
<a name="setting-up-the-deletepost-resolver-ddb-deletepost"></a>

La prochaine mutation que vous allez configurer permettra de supprimer une publication. Pour ce faire, utilisez l'opération `DeleteItem` DynamoDB.
+ Choisissez l'onglet **Schéma**.
+ Dans le volet **Schéma**, modifiez le type `Mutation` pour ajouter une nouvelle mutation `deletePost` :

  ```
  type Mutation {
      deletePost(id: ID!, expectedVersion: Int): Post
      upvotePost(id: ID!): Post
      downvotePost(id: ID!): Post
      updatePost(
          id: ID!,
          author: String,
          title: String,
          content: String,
          url: String,
          expectedVersion: Int!
      ): Post
      addPost(
          author: String!,
          title: String!,
          content: String!,
          url: String!
      ): Post!
  }
  ```

  Cette fois vous avez rendu le champ `expectedVersion` facultatif, ce qui est expliqué plus loin lorsque vous ajoutez le modèle de mappage de demande.
+ Choisissez **Enregistrer**.
+ Dans le volet **Types de données** sur la droite, se trouve le champ **delete** qui vient d'être créé, sur le type **Mutation**, choisissez ensuite **Joindre**.
+ Dans le **menu Action**, choisissez **Update runtime**, puis **Unit Resolver (VTL uniquement**).
+ Dans **Nom de la source de données**, choisissez **PostDynamoDBTable**.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de demande** :

  ```
  {
      "version" : "2017-02-28",
      "operation" : "DeleteItem",
      "key": {
          "id": $util.dynamodb.toDynamoDBJson($context.arguments.id)
      }
      #if( $context.arguments.containsKey("expectedVersion") )
          ,"condition" : {
              "expression"       : "attribute_not_exists(id) OR version = :expectedVersion",
              "expressionValues" : {
                  ":expectedVersion" : $util.dynamodb.toDynamoDBJson($context.arguments.expectedVersion)
              }
          }
      #end
  }
  ```

   **Remarque :** l'argument `expectedVersion` est un argument facultatif. Si l'appelant définit un `expectedVersion` argument dans la demande, le modèle ajoute une condition qui permet à la `DeleteItem` demande de réussir uniquement si l'élément est déjà supprimé ou si l'`version`attribut de la publication dans DynamoDB correspond exactement au. `expectedVersion` En cas d'omission, aucune expression de condition n'est spécifiée dans la demande `DeleteItem`. Il réussit quelle que soit la valeur de l'`version`élément ou qu'il existe ou non dans DynamoDB.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de réponse** :

  ```
  $utils.toJson($context.result)
  ```

   **Remarque :** même si vous supprimez un élément, vous pouvez renvoyer l'élément qui a été supprimé, s'il n'était pas déjà supprimé.
+ Choisissez **Enregistrer**.

Pour plus d'informations sur le mappage des `DeleteItem` demandes, consultez la documentation de [DeleteItem](aws-appsync-resolver-mapping-template-reference-dynamodb-deleteitem.md)référence.

### Appel de l'API pour supprimer une publication
<a name="call-the-api-to-delete-a-post"></a>

Maintenant que le résolveur est configuré, AWS AppSync il sait comment traduire une `delete` mutation entrante en une opération DynamoDB`DeleteItem`. Vous pouvez désormais exécuter une mutation pour supprimer quelque chose dans la table.
+ Choisissez l'onglet **Requêtes**.
+ Collez la mutation suivante dans le volet **Requêtes**. Vous devrez également mettre à jour l'argument `id` pour qu'il ait la valeur que vous avez notée précédemment.

  ```
  mutation deletePost {
    deletePost(id:123) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ La publication est supprimée de DynamoDB. Notez que cela AWS AppSync renvoie la valeur de l'élément qui a été supprimé de DynamoDB, qui doit apparaître dans le volet des résultats à droite du volet des requêtes. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "deletePost": {
        "id": "123",
        "author": "A new author",
        "title": "An empty story",
        "content": null,
        "url": "https://aws.amazon.com/appsync/",
        "ups": 6,
        "downs": 4,
        "version": 12
      }
    }
  }
  ```

La valeur est renvoyée seulement si cet appel à `deletePost` est celui qui l'a réellement supprimée de DynamoDB.
+ Choisissez **Exécuter une requête** à nouveau.
+ L'appel réussit quand même, mais aucune valeur n'est renvoyée.

  ```
  {
    "data": {
      "deletePost": null
    }
  }
  ```

Maintenant, essayons de supprimer une publication, mais cette fois en spécifiant `expectedValue`. Tout d'abord, vous devez créer une nouvelle publication, car vous venez de supprimer celle que vous utilisiez jusqu'à présent.
+ Collez la mutation suivante dans le volet **Requêtes**.

  ```
  mutation addPost {
    addPost(
      id:123
      author: "AUTHORNAME"
      title: "Our second post!"
      content: "A new post."
      url: "https://aws.amazon.com/appsync/"
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ Les résultats de la publication nouvellement créée doivent apparaître dans le volet des résultats à droite du volet de requête. Notez l'`id` de l'objet nouvellement créé, car vous en aurez besoin sous peu. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "addPost": {
        "id": "123",
        "author": "AUTHORNAME",
        "title": "Our second post!",
        "content": "A new post.",
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 1
      }
    }
  }
  ```

Maintenant, essayons de supprimer cette publication, mais insérons une valeur incorrecte pour `expectedVersion` :
+ Collez la mutation suivante dans le volet **Requêtes**. Vous devrez également mettre à jour l'argument `id` pour qu'il ait la valeur que vous avez notée précédemment.

  ```
  mutation deletePost {
    deletePost(
      id:123
      expectedVersion: 9999
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).

  ```
  {
    "data": {
      "deletePost": null
    },
    "errors": [
      {
        "path": [
          "deletePost"
        ],
        "data": {
          "id": "123",
          "author": "AUTHORNAME",
          "title": "Our second post!",
          "content": "A new post.",
          "url": "https://aws.amazon.com/appsync/",
          "ups": 1,
          "downs": 0,
          "version": 1
        },
        "errorType": "DynamoDB:ConditionalCheckFailedException",
        "locations": [
          {
            "line": 2,
            "column": 3
          }
        ],
        "message": "The conditional request failed (Service: AmazonDynamoDBv2; Status Code: 400; Error Code: ConditionalCheckFailedException; Request ID: ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ)"
      }
    ]
  }
  ```

  La demande a échoué car l'expression de la condition est fausse : la valeur `version` de la publication dans DynamoDB ne correspond pas à celle spécifiée dans `expectedValue` les arguments. La valeur actuelle de l'objet est renvoyée dans le champ `data` de la section `errors` de la réponse GraphQL.
+ Réessayez la demande, mais corrigez `expectedVersion` :

  ```
  mutation deletePost {
    deletePost(
      id:123
      expectedVersion: 1
    ) {
      id
      author
      title
      content
      url
      ups
      downs
      version
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ Cette fois, la demande aboutit et la valeur supprimée de DynamoDB est renvoyée :

  ```
  {
    "data": {
      "deletePost": {
        "id": "123",
        "author": "AUTHORNAME",
        "title": "Our second post!",
        "content": "A new post.",
        "url": "https://aws.amazon.com/appsync/",
        "ups": 1,
        "downs": 0,
        "version": 1
      }
    }
  }
  ```
+ Choisissez **Exécuter une requête** à nouveau.
+ L'appel réussit toujours, mais cette fois aucune valeur n'est renvoyée car la publication a déjà été supprimée dans DynamoDB.

```
{
  "data": {
    "deletePost": null
  }
}
```

## Configuration du résolveur allPost (DynamoDB Scan)
<a name="setting-up-the-allpost-resolver-dynamodb-scan"></a>

Jusqu'à présent, l'API est utile uniquement si vous connaissez l’`id` de chaque publication que vous voulez regarder. Ajoutons un nouveau résolveur qui renvoie toutes les publications de la table.
+ Choisissez l'onglet **Schéma**.
+ Dans le volet **Schéma**, modifiez le type `Query` pour ajouter une nouvelle requête `allPost` :

  ```
  type Query {
      allPost(count: Int, nextToken: String): PaginatedPosts!
      getPost(id: ID): Post
  }
  ```
+ Ajouter un nouveau type `PaginationPosts` :

  ```
  type PaginatedPosts {
      posts: [Post!]!
      nextToken: String
  }
  ```
+ Choisissez **Enregistrer**.
+ Dans le volet **Types de données** sur la droite, se trouve le champ **allPost** qui vient d'être créé, sur le type **Requête**, choisissez ensuite **Joindre**.
+ Dans le **menu Action**, choisissez **Update runtime**, puis **Unit Resolver (VTL uniquement**).
+ Dans **Nom de la source de données**, choisissez **PostDynamoDBTable**.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de demande** :

  ```
  {
      "version" : "2017-02-28",
      "operation" : "Scan"
      #if( ${context.arguments.count} )
          ,"limit": $util.toJson($context.arguments.count)
      #end
      #if( ${context.arguments.nextToken} )
          ,"nextToken": $util.toJson($context.arguments.nextToken)
      #end
  }
  ```

  Ce résolveur possède deux arguments facultatifs : `count`, qui spécifie le nombre maximal d'éléments à renvoyer dans un seul appel, et `nextToken`, qui peut être utilisé pour récupérer l'ensemble de résultats suivant (vous indiquerez ultérieurement d'où provient la valeur de `nextToken`).
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de réponse** :

  ```
  {
      "posts": $utils.toJson($context.result.items)
      #if( ${context.result.nextToken} )
          ,"nextToken": $util.toJson($context.result.nextToken)
      #end
  }
  ```

   **Remarque :** ce modèle de mappage de réponse est différent de tous les autres jusqu'à présent. Le résultat de la requête `allPost` est un `PaginatedPosts`, qui contient une liste de publications et un jeton de pagination. La forme de cet objet est différente de celle renvoyée par le résolveur AWS AppSync DynamoDB : la liste des publications est appelée `items` dans les résultats du résolveur AWS AppSync DynamoDB, mais elle est appelée. `posts` `PaginatedPosts`
+ Choisissez **Enregistrer**.

Pour en savoir plus sur le mappage des demandes `Scan`, consultez la documentation de référence [Scan](aws-appsync-resolver-mapping-template-reference-dynamodb-scan.md).

### Appel de l'API pour analyser toutes les publications
<a name="call-the-api-to-scan-all-posts"></a>

Maintenant que le résolveur est configuré, AWS AppSync il sait comment traduire une `allPost` requête entrante en une opération DynamoDB`Scan`. Vous pouvez désormais analyser la table pour récupérer toutes les publications.

Avant de pouvoir essayer, vous avez besoin de remplir la table avec certaines données, car vous avez supprimé tout ce que vous aviez utilisé jusque là.
+ Choisissez l'onglet **Requêtes**.
+ Collez la mutation suivante dans le volet **Requêtes**.

  ```
  mutation addPost {
    post1: addPost(id:1 author: "AUTHORNAME" title: "A series of posts, Volume 1" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post2: addPost(id:2 author: "AUTHORNAME" title: "A series of posts, Volume 2" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post3: addPost(id:3 author: "AUTHORNAME" title: "A series of posts, Volume 3" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post4: addPost(id:4 author: "AUTHORNAME" title: "A series of posts, Volume 4" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post5: addPost(id:5 author: "AUTHORNAME" title: "A series of posts, Volume 5" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post6: addPost(id:6 author: "AUTHORNAME" title: "A series of posts, Volume 6" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post7: addPost(id:7 author: "AUTHORNAME" title: "A series of posts, Volume 7" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post8: addPost(id:8 author: "AUTHORNAME" title: "A series of posts, Volume 8" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
    post9: addPost(id:9 author: "AUTHORNAME" title: "A series of posts, Volume 9" content: "Some content" url: "https://aws.amazon.com/appsync/" ) { title }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).

Maintenant, analysons la table, en renvoyant cinq résultats à la fois.
+ Collez la requête suivante dans le volet **Requêtes** :

  ```
  query allPost {
    allPost(count: 5) {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ Les cinq premières publications doivent apparaître dans le volet des résultats à droite du volet de requête. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "allPost": {
        "posts": [
          {
            "id": "5",
            "title": "A series of posts, Volume 5"
          },
          {
            "id": "1",
            "title": "A series of posts, Volume 1"
          },
          {
            "id": "6",
            "title": "A series of posts, Volume 6"
          },
          {
            "id": "9",
            "title": "A series of posts, Volume 9"
          },
          {
            "id": "7",
            "title": "A series of posts, Volume 7"
          }
        ],
        "nextToken": "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnRkJEdXdUK09hcnovRGhNTGxLTGdMUEFBQUI1akNDQWVJR0NTcUdTSWIzRFFFSEJxQ0NBZE13Z2dIUEFnRUFNSUlCeUFZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF6ajFodkhKU1paT1pncTRaUUNBUkNBZ2dHWnJiR1dQWGxkMDB1N0xEdGY4Z2JsbktzRjRua1VCcks3TFJLcjZBTFRMeGFwVGJZMDRqOTdKVFQyYVRwSzdzbVdtNlhWWFVCTnFIOThZTzBWZHVkdDI2RlkxMHRqMDJ2QTlyNWJTUWpTbWh6NE5UclhUMG9KZWJSQ2JJbXBlaDRSVlg0Tis0WTVCN1IwNmJQWWQzOVhsbTlUTjBkZkFYMVErVCthaXZoNE5jMk50RitxVmU3SlJ5WmpzMEFkSGduM3FWd2VrOW5oeFVVd3JlK1loUks5QkRzemdiMDlmZmFPVXpzaFZ4cVJRbC93RURlOTcrRmVJdXZNby9NZ1F6dUdNbFRyalpNR3FuYzZBRnhwa0VlZTFtR0FwVDFISElUZlluakptYklmMGUzUmcxbVlnVHVSbDh4S0trNmR0QVoraEhLVDhuNUI3VnF4bHRtSnlNUXBrZGl6KzkyL3VzNDl4OWhrMnVxSW01ZFFwMjRLNnF0dm9ZK1BpdERuQTc5djhzb0grVytYT3VuQ2NVVDY4TVZ1Wk5KYkRuSEFSSEVlaTlVNVBTelU5RGZ6d2pPdmhqWDNJMWhwdWUrWi83MDVHVjlPQUxSTGlwZWZPeTFOZFhwZTdHRDZnQW00bUJUK2c1eC9Ec3ZDbWVnSDFDVXRTdHVuU1ZFa2JpZytQRC9oMUwyRTNqSHhVQldaa28yU256WUc0cG0vV1RSWkFVZHZuQT09In0="
      }
    }
  }
  ```

Vous avez cinq résultats et un `nextToken` que vous pouvez utiliser pour obtenir l'ensemble de résultats suivant.
+ Mettez à jour la requête `allPost` pour qu'elle inclue l'élément `nextToken` issu de l'ensemble de résultats précédent :

  ```
  query allPost {
    allPost(
      count: 5
      nextToken: "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnRlluNktJRWl6V0ZlR3hJOVJkaStrZUFBQUI1akNDQWVJR0NTcUdTSWIzRFFFSEJxQ0NBZE13Z2dIUEFnRUFNSUlCeUFZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5cW8yUGFSZThnalFpemRCTUNBUkNBZ2dHWk1JODhUNzhIOFVUZGtpdFM2ZFluSWRyVDg4c2lkN1RjZzB2d1k3VGJTTWpSQ2U3WjY3TkUvU2I1dWNETUdDMmdmMHErSGJSL0pteGRzYzVEYnE1K3BmWEtBdU5jSENJdWNIUkJ0UHBPWVdWdCtsS2U5L1pNcWdocXhrem1RaXI1YnIvQkt6dU5hZmJCdE93NmtoM2Jna1BKM0RjWWhpMFBGbmhMVGg4TUVGSjBCcXg3RTlHR1V5N0tUS0JLZlV3RjFQZ0JRREdrNzFYQnFMK2R1S2IrVGtZZzVYMjFrc3NyQmFVTmNXZmhTeXE0ZUJHSWhqZWQ5c3VKWjBSSTc2ZnVQdlZkR3FLNENjQmxHYXhpekZnK2pKK1FneEU1SXduRTNYYU5TR0I4QUpmamR2bU1wbUk1SEdvWjlMUUswclczbG14RDRtMlBsaTNLaEVlcm9pem5zcmdINFpvcXIrN2ltRDN3QkJNd3BLbGQzNjV5Nnc4ZnMrK2FnbTFVOUlKOFFrOGd2bEgySHFROHZrZXBrMWlLdWRIQ25LaS9USnBlMk9JeEVPazVnRFlzRTRUU09HUlVJTkxYY2MvdW1WVEpBMUthV2hWTlAvdjNlSnlZQUszbWV6N2h5WHVXZ1BkTVBNWERQdTdjVnVRa3EwK3NhbGZOd2wvSUx4bHNyNDVwTEhuVFpyRWZvVlV1bXZ5S2VKY1RUU1lET05hM1NwWEd2UT09In0="
    ) {
      posts {
        id
        author
      }
      nextToken
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ Les quatre publications restantes doivent apparaître dans le volet des résultats à droite du volet de requête. Il n'y a pas d'élément `nextToken` dans cet ensemble de résultats, car vous avez parcouru les neuf publications, et il n'en reste aucune. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "allPost": {
        "posts": [
          {
            "id": "2",
            "title": "A series of posts, Volume 2"
          },
          {
            "id": "3",
            "title": "A series of posts, Volume 3"
          },
          {
            "id": "4",
            "title": "A series of posts, Volume 4"
          },
          {
            "id": "8",
            "title": "A series of posts, Volume 8"
          }
        ],
        "nextToken": null
      }
    }
  }
  ```

## Configuration du résolveur d' allPostsByauteur (requête DynamoDB)
<a name="setting-up-the-allpostsbyauthor-resolver-ddb-query"></a>

En plus de rechercher dans DynamoDB toutes les publications, vous pouvez également interroger DynamoDB pour récupérer les publications créées par un auteur spécifique. La table DynamoDB que vous avez créée précédemment possède déjà `GlobalSecondaryIndex` un `author-index` appel que vous pouvez utiliser avec une opération DynamoDB pour récupérer toutes les `Query` publications créées par un auteur spécifique.
+ Choisissez l'onglet **Schéma**.
+ Dans le volet **Schéma**, modifiez le type `Query` pour ajouter une nouvelle requête `allPostsByAuthor` :

  ```
  type Query {
      allPostsByAuthor(author: String!, count: Int, nextToken: String): PaginatedPosts!
      allPost(count: Int, nextToken: String): PaginatedPosts!
      getPost(id: ID): Post
  }
  ```

   **Remarque :** ceci utilise le même type `PaginatedPosts` que nous avons utilisé avec la requête `allPost`.
+ Choisissez **Enregistrer**.
+ Dans le volet **Types de données** sur la droite, recherchez le champ **allPostsByAuteur** nouvellement créé dans le type de **requête**, puis choisissez **Joindre**.
+ Dans le **menu Action**, choisissez **Update runtime**, puis **Unit Resolver (VTL uniquement**).
+ Dans **Nom de la source de données**, choisissez **PostDynamoDBTable**.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de demande** :

  ```
  {
      "version" : "2017-02-28",
      "operation" : "Query",
      "index" : "author-index",
      "query" : {
        "expression": "author = :author",
          "expressionValues" : {
            ":author" : $util.dynamodb.toDynamoDBJson($context.arguments.author)
          }
      }
      #if( ${context.arguments.count} )
          ,"limit": $util.toJson($context.arguments.count)
      #end
      #if( ${context.arguments.nextToken} )
          ,"nextToken": "${context.arguments.nextToken}"
      #end
  }
  ```

  Comme le résolveur `allPost`, ce résolveur possède deux arguments facultatifs : `count`, qui spécifie le nombre maximal d'éléments à renvoyer dans un seul appel et `nextToken`, qui peut être utilisé pour récupérer l'ensemble de résultats suivant (la valeur de `nextToken` peut être obtenue à partir d'un appel précédent).
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de réponse** :

  ```
  {
      "posts": $utils.toJson($context.result.items)
      #if( ${context.result.nextToken} )
          ,"nextToken": $util.toJson($context.result.nextToken)
      #end
  }
  ```

   **Remarque :** il s'agit du même modèle de mappage de réponse que vous avez utilisé dans le résolveur `allPost`.
+ Choisissez **Enregistrer**.

Pour en savoir plus sur le mappage des demandes `Query`, consultez la documentation de référence [Requête](aws-appsync-resolver-mapping-template-reference-dynamodb-query.md).

### Appel de l'API pour interroger toutes les publications d'un auteur
<a name="call-the-api-to-query-all-posts-by-an-author"></a>

Maintenant que le résolveur est configuré, AWS AppSync il sait comment traduire une `allPostsByAuthor` mutation entrante en une opération `Query` DynamoDB par rapport à l'index. `author-index` Vous pouvez désormais interroger la table pour récupérer toutes les publications d'un auteur spécifique.

Avant cela, toutefois, remplissez la table avec d'autres publications car, à ce stade, chaque publication est du même auteur.
+ Choisissez l'onglet **Requêtes**.
+ Collez la mutation suivante dans le volet **Requêtes**.

  ```
  mutation addPost {
    post1: addPost(id:10 author: "Nadia" title: "The cutest dog in the world" content: "So cute. So very, very cute." url: "https://aws.amazon.com/appsync/" ) { author, title }
    post2: addPost(id:11 author: "Nadia" title: "Did you know...?" content: "AppSync works offline?" url: "https://aws.amazon.com/appsync/" ) { author, title }
    post3: addPost(id:12 author: "Steve" title: "I like GraphQL" content: "It's great" url: "https://aws.amazon.com/appsync/" ) { author, title }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).

Maintenant, interrogez la table et renvoyez toutes les publications créées par `Nadia`.
+ Collez la requête suivante dans le volet **Requêtes** :

  ```
  query allPostsByAuthor {
    allPostsByAuthor(author: "Nadia") {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ Toutes les publications créées par `Nadia` doivent apparaître dans le volet des résultats à droite du volet de requête. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "allPostsByAuthor": {
        "posts": [
          {
            "id": "10",
            "title": "The cutest dog in the world"
          },
          {
            "id": "11",
            "title": "Did you know...?"
          }
        ],
        "nextToken": null
      }
    }
  }
  ```

La pagination fonctionne pour `Query` tout comme elle le fait pour `Scan`. Par exemple, examinons toutes les publications créées par `AUTHORNAME`, et prenons-en cinq à la fois.
+ Collez la requête suivante dans le volet **Requêtes** :

  ```
  query allPostsByAuthor {
    allPostsByAuthor(
      author: "AUTHORNAME"
      count: 5
    ) {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ Toutes les publications créées par `AUTHORNAME` doivent apparaître dans le volet des résultats à droite du volet de requête. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "allPostsByAuthor": {
        "posts": [
          {
            "id": "6",
            "title": "A series of posts, Volume 6"
          },
          {
            "id": "4",
            "title": "A series of posts, Volume 4"
          },
          {
            "id": "2",
            "title": "A series of posts, Volume 2"
          },
          {
            "id": "7",
            "title": "A series of posts, Volume 7"
          },
          {
            "id": "1",
            "title": "A series of posts, Volume 1"
          }
        ],
        "nextToken": "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnSExqRnVhVUR3ZUhEZ2QzNGJ2QlFuY0FBQUNqekNDQW9zR0NTcUdTSWIzRFFFSEJxQ0NBbnd3Z2dKNEFnRUFNSUlDY1FZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5Qkg4Yk1obW9LVEFTZHM3SUNBUkNBZ2dKQ3dISzZKNlJuN3pyYUVKY1pWNWxhSkNtZW1KZ0F5N1dhZkc2UEdTNHpNQzJycTkwZHFJTFV6Z25wck9Gd3pMS3VOQ2JvUXc3VDI5eCtnVExIbGg4S3BqbzB1YjZHQ3FwcDhvNDVmMG9JbDlmdS9JdjNXcFNNSXFKTXZ1MEVGVWs1VzJQaW5jZGlUaVRtZFdYWlU1bkV2NkgyRFBRQWZYYlNnSmlHSHFLbmJZTUZZM0FTdmRIL0hQaVZBb1RCMk1YZkg0eGJOVTdEbjZtRFNhb2QwbzdHZHJEWDNtODQ1UXBQUVNyUFhHemY0WDkyajhIdlBCSWE4Smcrb0RxbHozUVQ5N2FXUXdYWWU2S0h4emI1ejRITXdEdXEyRDRkYzhoMi9CbW10MzRMelVGUVIyaExSZGRaZ0xkdzF5cHJZdFZwY3dEc1d4UURBTzdOcjV2ZEp4VVR2TVhmODBRSnp1REhXREpTVlJLdDJwWmlpaXhXeGRwRmNod1BzQ3d2aVBqMGwrcWFFWU1jMXNQbENkVkFGem43VXJrSThWbS8wWHlwR2xZb3BSL2FkV0xVekgrbGMrYno1ZEM2SnVLVXdtY1EyRXlZeDZiS0Izbi9YdUViWGdFeU5PMWZTdE1rRlhyWmpvMVpzdlYyUFRjMzMrdEs0ZDhkNkZrdjh5VVR6WHhJRkxIaVNsOUx6VVdtT3BCaWhrTFBCT09jcXkyOHh1UmkzOEM3UFRqMmN6c3RkOUo1VUY0azBJdUdEbVZzM2xjdWg1SEJjYThIeXM2aEpvOG1HbFpMNWN6R2s5bi8vRE1EbDY3RlJraG5QNFNhSDBpZGI5VFEvMERLeFRBTUdhcWpPaEl5ekVqd2ZDQVJleFdlbldyOGlPVkhScDhGM25WZVdvbFRGK002N0xpdi9XNGJXdDk0VEg3b0laUU5lYmZYKzVOKy9Td25Hb1dyMTlWK0pEb2lIRVFLZ1cwMWVuYjZKUXo5Slh2Tm95ZzF3RnJPVmxGc2xwNlRHa1BlN2Rnd2IrWT0ifQ=="
      }
    }
  }
  ```
+ Mettez à jour l'argument `nextToken` avec la valeur renvoyée par la requête précédente :

  ```
  query allPostsByAuthor {
    allPostsByAuthor(
      author: "AUTHORNAME"
      count: 5
      nextToken: "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnSExqRnVhVUR3ZUhEZ2QzNGJ2QlFuY0FBQUNqekNDQW9zR0NTcUdTSWIzRFFFSEJxQ0NBbnd3Z2dKNEFnRUFNSUlDY1FZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5Qkg4Yk1obW9LVEFTZHM3SUNBUkNBZ2dKQ3dISzZKNlJuN3pyYUVKY1pWNWxhSkNtZW1KZ0F5N1dhZkc2UEdTNHpNQzJycTkwZHFJTFV6Z25wck9Gd3pMS3VOQ2JvUXc3VDI5eCtnVExIbGg4S3BqbzB1YjZHQ3FwcDhvNDVmMG9JbDlmdS9JdjNXcFNNSXFKTXZ1MEVGVWs1VzJQaW5jZGlUaVRtZFdYWlU1bkV2NkgyRFBRQWZYYlNnSmlHSHFLbmJZTUZZM0FTdmRIL0hQaVZBb1RCMk1YZkg0eGJOVTdEbjZtRFNhb2QwbzdHZHJEWDNtODQ1UXBQUVNyUFhHemY0WDkyajhIdlBCSWE4Smcrb0RxbHozUVQ5N2FXUXdYWWU2S0h4emI1ejRITXdEdXEyRDRkYzhoMi9CbW10MzRMelVGUVIyaExSZGRaZ0xkdzF5cHJZdFZwY3dEc1d4UURBTzdOcjV2ZEp4VVR2TVhmODBRSnp1REhXREpTVlJLdDJwWmlpaXhXeGRwRmNod1BzQ3d2aVBqMGwrcWFFWU1jMXNQbENkVkFGem43VXJrSThWbS8wWHlwR2xZb3BSL2FkV0xVekgrbGMrYno1ZEM2SnVLVXdtY1EyRXlZeDZiS0Izbi9YdUViWGdFeU5PMWZTdE1rRlhyWmpvMVpzdlYyUFRjMzMrdEs0ZDhkNkZrdjh5VVR6WHhJRkxIaVNsOUx6VVdtT3BCaWhrTFBCT09jcXkyOHh1UmkzOEM3UFRqMmN6c3RkOUo1VUY0azBJdUdEbVZzM2xjdWg1SEJjYThIeXM2aEpvOG1HbFpMNWN6R2s5bi8vRE1EbDY3RlJraG5QNFNhSDBpZGI5VFEvMERLeFRBTUdhcWpPaEl5ekVqd2ZDQVJleFdlbldyOGlPVkhScDhGM25WZVdvbFRGK002N0xpdi9XNGJXdDk0VEg3b0laUU5lYmZYKzVOKy9Td25Hb1dyMTlWK0pEb2lIRVFLZ1cwMWVuYjZKUXo5Slh2Tm95ZzF3RnJPVmxGc2xwNlRHa1BlN2Rnd2IrWT0ifQ=="
    ) {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ Les publications créées par `AUTHORNAME` doivent apparaître dans le volet des résultats à droite du volet de requête. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "allPostsByAuthor": {
        "posts": [
          {
            "id": "8",
            "title": "A series of posts, Volume 8"
          },
          {
            "id": "5",
            "title": "A series of posts, Volume 5"
          },
          {
            "id": "3",
            "title": "A series of posts, Volume 3"
          },
          {
            "id": "9",
            "title": "A series of posts, Volume 9"
          }
        ],
        "nextToken": null
      }
    }
  }
  ```

## Utilisation des ensembles
<a name="using-sets"></a>

Jusqu'à présent, le `Post` type était un key/value objet plat. Vous pouvez également modéliser des objets complexes avec le résolveur AWS AppSyncDynamo de base de données, tels que des ensembles, des listes et des cartes.

Mettons à jour notre type `Post` pour inclure des balises. Une publication peut comporter 0 balises ou plus, qui sont stockées dans DynamoDB sous forme de jeu de chaînes. Vous allez également configurer certaines mutations pour ajouter et supprimer des balises, et une nouvelle requête pour rechercher des publications avec une balise spécifique.
+ Choisissez l'onglet **Schéma**.
+ Dans le volet **Schéma**, modifiez le type `Post` pour ajouter un nouveau champ `tags` :

  ```
  type Post {
    id: ID!
    author: String
    title: String
    content: String
    url: String
    ups: Int!
    downs: Int!
    version: Int!
    tags: [String!]
  }
  ```
+ Dans le volet **Schéma**, modifiez le type `Query` pour ajouter une nouvelle requête `allPostsByTag` :

  ```
  type Query {
    allPostsByTag(tag: String!, count: Int, nextToken: String): PaginatedPosts!
    allPostsByAuthor(author: String!, count: Int, nextToken: String): PaginatedPosts!
    allPost(count: Int, nextToken: String): PaginatedPosts!
    getPost(id: ID): Post
  }
  ```
+ Dans le volet **Schéma**, modifiez le type `Mutation` pour ajouter de nouvelles mutations `addTag` et `removeTag` :

  ```
  type Mutation {
    addTag(id: ID!, tag: String!): Post
    removeTag(id: ID!, tag: String!): Post
    deletePost(id: ID!, expectedVersion: Int): Post
    upvotePost(id: ID!): Post
    downvotePost(id: ID!): Post
    updatePost(
      id: ID!,
      author: String,
      title: String,
      content: String,
      url: String,
      expectedVersion: Int!
    ): Post
    addPost(
      author: String!,
      title: String!,
      content: String!,
      url: String!
    ): Post!
  }
  ```
+ Choisissez **Enregistrer**.
+ Dans le volet **Types de données** sur la droite, recherchez le champ **allPostsByTag** nouvellement créé dans le type de **requête**, puis choisissez **Joindre**.
+ Dans **Nom de la source de données**, choisissez **PostDynamoDBTable**.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de demande** :

  ```
  {
      "version" : "2017-02-28",
      "operation" : "Scan",
      "filter": {
        "expression": "contains (tags, :tag)",
          "expressionValues": {
            ":tag": $util.dynamodb.toDynamoDBJson($context.arguments.tag)
          }
      }
      #if( ${context.arguments.count} )
          ,"limit": $util.toJson($context.arguments.count)
      #end
      #if( ${context.arguments.nextToken} )
          ,"nextToken": $util.toJson($context.arguments.nextToken)
      #end
  }
  ```
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de réponse** :

  ```
  {
      "posts": $utils.toJson($context.result.items)
      #if( ${context.result.nextToken} )
          ,"nextToken": $util.toJson($context.result.nextToken)
      #end
  }
  ```
+ Choisissez **Enregistrer**.
+ Dans le volet **Types de données** sur la droite, se trouve le champ **addTag** qui vient d'être créé, sur le type **Mutation**, choisissez ensuite **Joindre**.
+ Dans **Nom de la source de données**, choisissez **PostDynamoDBTable**.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de demande** :

  ```
  {
      "version" : "2017-02-28",
      "operation" : "UpdateItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
      },
      "update" : {
          "expression" : "ADD tags :tags, version :plusOne",
          "expressionValues" : {
              ":tags" : { "SS": [ $util.toJson($context.arguments.tag) ] },
              ":plusOne" : { "N" : 1 }
          }
      }
  }
  ```
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de réponse** :

  ```
  $utils.toJson($context.result)
  ```
+ Choisissez **Enregistrer**.
+ Dans le volet **Types de données** sur la droite, se trouve le champ **removeTag** qui vient d'être créé, sur le type **Mutation**, choisissez ensuite **Joindre**.
+ Dans **Nom de la source de données**, choisissez **PostDynamoDBTable**.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de demande** :

  ```
  {
      "version" : "2017-02-28",
      "operation" : "UpdateItem",
      "key" : {
          "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
      },
      "update" : {
          "expression" : "DELETE tags :tags ADD version :plusOne",
          "expressionValues" : {
              ":tags" : { "SS": [ $util.toJson($context.arguments.tag) ] },
              ":plusOne" : { "N" : 1 }
          }
      }
  }
  ```
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de réponse** :

  ```
  $utils.toJson($context.result)
  ```
+ Choisissez **Enregistrer**.

### Appel de l'API pour utiliser des balises
<a name="call-the-api-to-work-with-tags"></a>

Maintenant que vous avez configuré les résolveurs, vous savez comment AWS AppSync traduire les requêtes entrantes et `addTag` les `removeTag` `allPostsByTag` requêtes en `UpdateItem` DynamoDB `Scan` et en opérations.

Pour tester cela, sélectionnons l'une des publications que nous avons créées précédemment. Par exemple, utilisons un article créé par `Nadia`.
+ Choisissez l'onglet **Requêtes**.
+ Collez la requête suivante dans le volet **Requêtes** :

  ```
  query allPostsByAuthor {
    allPostsByAuthor(
      author: "Nadia"
    ) {
      posts {
        id
        title
      }
      nextToken
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ Toutes les publications de Nadia doivent apparaître dans le volet des résultats à droite du volet de requête. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "allPostsByAuthor": {
        "posts": [
          {
            "id": "10",
            "title": "The cutest dog in the world"
          },
          {
            "id": "11",
            "title": "Did you known...?"
          }
        ],
        "nextToken": null
      }
    }
  }
  ```
+ Utilisons celui avec le titre `"The cutest dog in the world"`. Notez son `id` car vous l'utiliserez ultérieurement.

Essayons maintenant d'ajouter une balise `dog`.
+ Collez la mutation suivante dans le volet **Requêtes**. Vous devrez également mettre à jour l'argument `id` pour qu'il ait la valeur que vous avez notée précédemment.

  ```
  mutation addTag {
    addTag(id:10 tag: "dog") {
      id
      title
      tags
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ La publication est mise à jour avec la nouvelle balise.

  ```
  {
    "data": {
      "addTag": {
        "id": "10",
        "title": "The cutest dog in the world",
        "tags": [
          "dog"
        ]
      }
    }
  }
  ```

Vous pouvez ajouter encore d'autres balises :
+ Mettez à jour la mutation pour modifier l'argument `tag` en spécifiant `puppy`.

  ```
  mutation addTag {
    addTag(id:10 tag: "puppy") {
      id
      title
      tags
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ La publication est mise à jour avec la nouvelle balise.

  ```
  {
    "data": {
      "addTag": {
        "id": "10",
        "title": "The cutest dog in the world",
        "tags": [
          "dog",
          "puppy"
        ]
      }
    }
  }
  ```

Vous pouvez également supprimer des balises :
+ Collez la mutation suivante dans le volet **Requêtes**. Vous devrez également mettre à jour l'argument `id` pour qu'il ait la valeur que vous avez notée précédemment.

  ```
  mutation removeTag {
    removeTag(id:10 tag: "puppy") {
      id
      title
      tags
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ La publication est mise à jour et la balise `puppy` est supprimée.

  ```
  {
    "data": {
      "addTag": {
        "id": "10",
        "title": "The cutest dog in the world",
        "tags": [
          "dog"
        ]
      }
    }
  }
  ```

Vous pouvez également rechercher toutes les publications qui ont une balise :
+ Collez la requête suivante dans le volet **Requêtes** :

  ```
  query allPostsByTag {
    allPostsByTag(tag: "dog") {
      posts {
        id
        title
        tags
      }
      nextToken
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ Toutes les publications qui ont la balise `dog` sont renvoyées :

  ```
  {
    "data": {
      "allPostsByTag": {
        "posts": [
          {
            "id": "10",
            "title": "The cutest dog in the world",
            "tags": [
              "dog",
              "puppy"
            ]
          }
        ],
        "nextToken": null
      }
    }
  }
  ```

## Utilisation de listes et de cartes
<a name="using-lists-and-maps"></a>

Outre les ensembles DynamoDB, vous pouvez également utiliser des listes et des cartes DynamoDB pour modéliser des données complexes dans un seul objet.

Ajoutons la possibilité d'ajouter des commentaires aux publications. Cela sera modélisé sous la forme d'une liste d'objets cartographiques sur l'`Post`objet dans DynamoDB.

 **Remarque :** dans une application réelle, vous devez modéliser les commentaires dans leur propre table. Dans le cadre de ce didacticiel, vous devez simplement les ajouter dans la table `Post`.
+ Choisissez l'onglet **Schéma**.
+ Dans le volet **Schéma**, ajoutez un nouveau type `Comment` :

  ```
  type Comment {
      author: String!
      comment: String!
  }
  ```
+ Dans le volet **Schéma**, modifiez le type `Post` pour ajouter un nouveau champ `comments` :

  ```
  type Post {
    id: ID!
    author: String
    title: String
    content: String
    url: String
    ups: Int!
    downs: Int!
    version: Int!
    tags: [String!]
    comments: [Comment!]
  }
  ```
+ Dans le volet **Schéma**, modifiez le type `Mutation` pour ajouter une nouvelle mutation `addComment` :

  ```
  type Mutation {
    addComment(id: ID!, author: String!, comment: String!): Post
    addTag(id: ID!, tag: String!): Post
    removeTag(id: ID!, tag: String!): Post
    deletePost(id: ID!, expectedVersion: Int): Post
    upvotePost(id: ID!): Post
    downvotePost(id: ID!): Post
    updatePost(
      id: ID!,
      author: String,
      title: String,
      content: String,
      url: String,
      expectedVersion: Int!
    ): Post
    addPost(
      author: String!,
      title: String!,
      content: String!,
      url: String!
    ): Post!
  }
  ```
+ Choisissez **Enregistrer**.
+ Dans le volet **Types de données** sur la droite, se trouve le champ **addComment** qui vient d'être créé, sur le type **Mutation**, choisissez ensuite **Joindre**.
+ Dans **Nom de la source de données**, choisissez **PostDynamoDBTable**.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de demande** :

  ```
  {
    "version" : "2017-02-28",
    "operation" : "UpdateItem",
    "key" : {
      "id" : $util.dynamodb.toDynamoDBJson($context.arguments.id)
    },
    "update" : {
      "expression" : "SET comments = list_append(if_not_exists(comments, :emptyList), :newComment) ADD version :plusOne",
      "expressionValues" : {
        ":emptyList": { "L" : [] },
        ":newComment" : { "L" : [
          { "M": {
            "author": $util.dynamodb.toDynamoDBJson($context.arguments.author),
            "comment": $util.dynamodb.toDynamoDBJson($context.arguments.comment)
            }
          }
        ] },
        ":plusOne" : $util.dynamodb.toDynamoDBJson(1)
      }
    }
  }
  ```

  Cette expression de mise à jour ajoute une liste contenant notre nouveau commentaire à la liste `comments` existante. Si la liste n'existe pas encore, elle sera créée.
+ Collez ce qui suit dans la section **Configurer le modèle de mappage de réponse** :

  ```
  $utils.toJson($context.result)
  ```
+ Choisissez **Enregistrer**.

### Appel de l'API pour ajouter un commentaire
<a name="call-the-api-to-add-a-comment"></a>

Maintenant que vous avez configuré les résolveurs, vous savez comment AWS AppSync traduire les `addComment` demandes entrantes en opérations DynamoDB`UpdateItem`.

Essayons cela en ajoutant un commentaire à la même publication à laquelle vous avez ajouté les balises.
+ Choisissez l'onglet **Requêtes**.
+ Collez la requête suivante dans le volet **Requêtes** :

  ```
  mutation addComment {
    addComment(
      id:10
      author: "Steve"
      comment: "Such a cute dog."
    ) {
      id
      comments {
        author
        comment
      }
    }
  }
  ```
+ Choisissez **Exécuter une requête** (le bouton de lecture orange).
+ Toutes les publications de Nadia doivent apparaître dans le volet des résultats à droite du volet de requête. Il doit ressembler à l’exemple ci-dessous.

  ```
  {
    "data": {
      "addComment": {
        "id": "10",
        "comments": [
          {
            "author": "Steve",
            "comment": "Such a cute dog."
          }
        ]
      }
    }
  }
  ```

Si vous exécutez la demande plusieurs fois, plusieurs commentaires seront ajoutés à la liste.

## Conclusion
<a name="conclusion"></a>

Dans ce didacticiel, vous avez créé une API qui nous permet de manipuler des objets Post dans DynamoDB à l'aide de AWS AppSync GraphQL. Pour plus d'informations, consultez la [Référence du modèle de mappage des résolveurs](resolver-mapping-template-reference.md#aws-appsync-resolver-mapping-template-reference).

Pour nettoyer, vous pouvez supprimer l'API AppSync GraphQL de la console.

Pour supprimer la table DynamoDB et le rôle IAM que vous avez créés pour ce didacticiel, vous pouvez exécuter les opérations suivantes pour supprimer la pile, ou accéder à `AWSAppSyncTutorialForAmazonDynamoDB` la console et supprimer CloudFormation la pile :

```
aws cloudformation delete-stack \
    --stack-name AWSAppSyncTutorialForAmazonDynamoDB
```