

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.

# AWS AppSync référence du modèle de mappage du résolveur pour Lambda
<a name="resolver-mapping-template-reference-lambda"></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/resolver-reference-js-version.html)

Vous pouvez utiliser des AWS AppSync fonctions et des résolveurs pour appeler les fonctions Lambda situées dans votre compte. Vous pouvez façonner les charges utiles de vos demandes et la réponse de vos fonctions Lambda avant de les renvoyer à vos clients. Vous pouvez également utiliser des modèles de mappage pour donner des indications AWS AppSync sur la nature de l'opération à invoquer. Cette section décrit les différents modèles de mappage pour les opérations Lambda prises en charge.

## Modèle de mappage des demandes
<a name="request-mapping-template"></a>

Le modèle de mappage de requêtes Lambda gère les champs liés à votre fonction Lambda :

```
{
  "version": string,
  "operation": Invoke|BatchInvoke,
  "payload": any type,
  "invocationType": RequestResponse|Event
}
```

Voici la représentation du schéma JSON du modèle de mappage de demandes Lambda une fois résolu :

```
{
  "definitions": {},
  "$schema": "https://json-schema.org/draft-06/schema#",
  "$id": "https://aws.amazon.com/appsync/request-mapping-template.json",
  "type": "object",
  "properties": {
    "version": {
      "$id": "/properties/version",
      "type": "string",
      "enum": [
        "2018-05-29"
      ],
      "title": "The Mapping template version.",
      "default": "2018-05-29"
    },
    "operation": {
      "$id": "/properties/operation",
      "type": "string",
      "enum": [
        "Invoke",
        "BatchInvoke"
      ],
      "title": "The Mapping template operation.",
      "description": "What operation to execute.",
      "default": "Invoke"
    },
    "payload": {},
    "invocationType": {
      "$id": "/properties/invocationType",
      "type": "string",
      "enum": [
        "RequestResponse",
        "Event"
      ],
      "title": "The Mapping template invocation type.",
      "description": "What invocation type to execute.",
      "default": "RequestResponse"
    }
  },
  "required": [
    "version",
    "operation"
  ],
  "additionalProperties": false
}
```

Voici un exemple qui utilise une `invoke` opération dont les données de charge utile sont le `getPost` champ d'un schéma GraphQL avec ses arguments issus du contexte :

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "payload": {
    "field": "getPost",
    "arguments": $util.toJson($context.arguments)
  }
}
```

L'intégralité du document de mappage est transmise en entrée à votre fonction Lambda, de sorte que l'exemple précédent ressemble désormais à ceci :

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "payload": {
    "field": "getPost",
    "arguments": {
      "id": "postId1"
    }
  }
}
```

### Version
<a name="version"></a>

Commun à tous les modèles de mappage de demandes, il `version` définit la version utilisée par le modèle. Le `version` est obligatoire et est une valeur statique :

```
"version": "2018-05-29"
```

### Opération
<a name="operation"></a>

La source de données Lambda vous permet de définir deux opérations `operation` sur le terrain : `Invoke` et. `BatchInvoke` L'`Invoke`opération permet de AWS AppSync savoir d'appeler votre fonction Lambda pour chaque résolveur de champs GraphQL. `BatchInvoke`indique de regrouper AWS AppSync les requêtes pour le champ GraphQL actuel. Le champ `operation` est obligatoire.

En effet`Invoke`, le modèle de mappage des demandes résolues correspond à la charge utile d'entrée de la fonction Lambda. Modifions l'exemple ci-dessus :

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
    "payload": {
      "arguments": $util.toJson($context.arguments)
    }
}
```

Ceci est résolu et transmis à la fonction Lambda, qui pourrait ressembler à ceci :

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
    "payload": {
      "arguments": {
        "id": "postId1"
      }
    }
}
```

En `BatchInvoke` effet, le modèle de mappage est appliqué à chaque résolveur de champs du lot. Par souci de concision, AWS AppSync fusionne toutes les `payload` valeurs du modèle de mappage résolues dans une liste sous un seul objet correspondant au modèle de mappage. Le modèle d'exemple suivant affiche la fusion :

```
{
  "version": "2018-05-29",
  "operation": "BatchInvoke",
  "payload": $util.toJson($context)
}
```

Ce modèle est résolu dans le document de mappage suivant :

```
{
  "version": "2018-05-29",
  "operation": "BatchInvoke",
  "payload": [
    {...}, // context for batch item 1
    {...}, // context for batch item 2
    {...}  // context for batch item 3
  ]
}
```

Chaque élément de la `payload` liste correspond à un seul article du lot. La fonction Lambda devrait également renvoyer une réponse sous forme de liste correspondant à l'ordre des éléments envoyés dans la demande :

```
[
  { "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 1
  { "data": {...}, "errorMessage": null, "errorType": null }, // result for batch item 2
  { "data": {...}, "errorMessage": null, "errorType": null }  // result for batch item 3
]
```

### Charge utile
<a name="payload"></a>

Le `payload` champ est un conteneur utilisé pour transmettre n'importe quel JSON bien formé à la fonction Lambda. Si le `operation` champ est défini sur`BatchInvoke`, AWS AppSync regroupe les `payload` valeurs existantes dans une liste. Le champ `payload` est facultatif.

### Types d’invocation
<a name="async-invocation-type"></a>

La source de données Lambda vous permet de définir deux types d'invocation : et. `RequestResponse` `Event` [Les types d'invocation sont synonymes des types d'invocation définis dans l'API Lambda.](https://docs.aws.amazon.com//lambda/latest/api/API_Invoke.html) Le type `RequestResponse` d'invocation permet d' AWS AppSync appeler votre fonction Lambda de manière synchrone pour attendre une réponse. L'`Event`invocation vous permet d'appeler votre fonction Lambda de manière asynchrone. [Pour plus d'informations sur la façon dont Lambda gère les demandes de type `Event` invocation, consultez Invocation asynchrone.](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html) Le champ `invocationType` est facultatif. Si ce champ n'est pas inclus dans la demande, le type d'`RequestResponse`appel AWS AppSync sera défini par défaut.

Quel que soit `invocationType` le champ, la demande résolue correspond à la charge utile d'entrée de la fonction Lambda. Modifions l'exemple ci-dessus :

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "invocationType": "Event"
  "payload": {
    "arguments": $util.toJson($context.arguments)
  }
}
```

Ceci est résolu et transmis à la fonction Lambda, qui pourrait ressembler à ceci :

```
{
  "version": "2018-05-29",
  "operation": "Invoke",
  "invocationType": "Event",
  "payload": {
    "arguments": {
      "id": "postId1"
    }
  }
}
```

Lorsque l'`BatchInvoke`opération est utilisée conjointement avec le champ de type d'`Event`appel, elle AWS AppSync fusionne le résolveur de champ de la même manière que celle mentionnée ci-dessus, et la demande est transmise à votre fonction Lambda sous forme d'événement asynchrone sous la forme d'une liste de valeurs. `payload` Nous vous recommandons de désactiver la mise en cache des résolveurs pour les résolveurs de type `Event` invocation, car ceux-ci ne seraient pas envoyés à Lambda en cas d'accès au cache.

## Modèle de mappage des réponses
<a name="response-mapping-template"></a>

Comme pour les autres sources de données, votre fonction Lambda envoie une réponse AWS AppSync qui doit être convertie en un type GraphQL.

Le résultat de la fonction Lambda est défini sur l'`context`objet disponible via la propriété Velocity Template Language (VTL). `$context.result`

Si la forme de la réponse de la fonction Lambda correspond exactement à celle du type GraphQL, vous pouvez transmettre la réponse à l'aide du modèle de mappage de réponse suivant :

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

Il n'y a pas de champs obligatoires ni de restrictions des formes qui s'appliquent au modèle de mappage de la réponse. Toutefois, dans la mesure où GraphQL est fortement typé, le modèle de mappage résolu doit correspondre au type GraphQL prévu.

## Réponse par lots de la fonction Lambda
<a name="aws-appsync-resolver-mapping-template-reference-lambda-batched-response"></a>

Si le champ `operation` est défini sur `BatchInvoke`, AWS AppSync attend une liste d'éléments renvoyée par la fonction Lambda. Afin de AWS AppSync faire correspondre chaque résultat à l'élément de demande d'origine, la liste de réponses doit correspondre en taille et en ordre. Il est valide d'avoir des `null` éléments dans la liste de réponses ; elle `$ctx.result` est définie sur *null* en conséquence.

## Résolveurs Lambda directs
<a name="direct-lambda-resolvers"></a>

Si vous souhaitez éviter complètement l'utilisation de modèles de mappage, vous AWS AppSync pouvez fournir une charge utile par défaut à votre fonction Lambda et une réponse de fonction Lambda par défaut à un type GraphQL. Vous pouvez choisir de fournir un modèle de demande, un modèle de réponse ou aucun des deux, et AWS AppSync le gérer en conséquence.

### Modèle de mappage de requêtes Lambda direct
<a name="lambda-mapping-template-bypass-request"></a>

Lorsque le modèle de mappage de demandes n'est pas fourni, l'`Context`objet AWS AppSync sera envoyé directement à votre fonction Lambda sous forme d'`Invoke`opération. Pour plus d'informations sur la structure de l'objet `Context`, consultez [AWS AppSync référence contextuelle du modèle de mappage du résolveur](resolver-context-reference.md).

### Modèle de mappage des réponses Lambda directes
<a name="lambda-mapping-template-bypass-response"></a>

Lorsque le modèle de mappage des réponses n'est pas fourni, AWS AppSync effectuez l'une des deux opérations suivantes après avoir reçu la réponse de votre fonction Lambda. Si vous n'avez pas fourni de modèle de mappage de demandes ou si vous avez fourni un modèle de mappage de demandes avec la version`2018-05-29`, la réponse sera équivalente au modèle de mappage de réponse suivant :

```
#if($ctx.error)
     $util.error($ctx.error.message, $ctx.error.type, $ctx.result)
 #end
 $util.toJson($ctx.result)
```

Si vous avez fourni un modèle avec la version`2017-02-28`, la logique de réponse fonctionne de la même manière que le modèle de mappage des réponses suivant :

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

À première vue, le contournement du modèle de mappage fonctionne de la même manière que l'utilisation de certains modèles de mappage, comme indiqué dans les exemples précédents. Cependant, dans les coulisses, l'évaluation des modèles de mappage est totalement contournée. Dans la mesure où l'étape d'évaluation du modèle est contournée, les applications peuvent être confrontées à moins de surcharge et de latence pendant la réponse dans certains scénarios par rapport à une fonction Lambda avec un modèle de mappage des réponses qui doit être évalué. 

### Gestion personnalisée des erreurs dans les réponses Direct Lambda Resolver
<a name="lambda-mapping-template-bypass-errors"></a>

Vous pouvez personnaliser les réponses aux erreurs issues des fonctions Lambda invoquées par les résolveurs Lambda directs en déclenchant une exception personnalisée. L'exemple suivant montre comment créer une exception personnalisée à l'aide de JavaScript :

```
class CustomException extends Error {
  constructor(message) {
    super(message);
    this.name = "CustomException";
  }
}
 
throw new CustomException("Custom message");
```

Lorsque des exceptions sont déclenchées, les `errorType` `name` et `errorMessage` `message` sont respectivement les et et de l'erreur personnalisée générée.

Si `errorType` tel est le cas`UnauthorizedException`, AWS AppSync renvoie le message par défaut (`"You are not authorized to make this call."`) au lieu d'un message personnalisé.

L'extrait suivant est un exemple de réponse GraphQL illustrant une personnalisation : `errorType`

```
{
  "data": {
    "query": null
  },
  "errors": [
    {
      "path": [
        "query"
      ],
      "data": null,
      "errorType": "CustomException",
      "errorInfo": null,
      "locations": [
        {
          "line": 5,
          "column": 10,
          "sourceName": null
        }
      ],
      "message": "Custom Message"
    }
  ]
}
```

### Résolveurs Lambda directs : le traitement par lots est activé
<a name="lambda-resolvers-batching"></a>

Vous pouvez activer le traitement par lots pour votre résolveur Lambda direct en le `maxBatchSize` configurant sur votre résolveur. Lorsqu'il `maxBatchSize` est défini sur une valeur supérieure à celle `0` d'un résolveur Lambda direct, il AWS AppSync envoie des requêtes par lots à votre fonction Lambda dans des tailles allant jusqu'à. `maxBatchSize` 

Le réglage `maxBatchSize` `0` sur sur un résolveur Direct Lambda désactive le traitement par lots.

Pour plus d'informations sur le fonctionnement du traitement par lots avec des résolveurs Lambda, consultez. [Cas d'utilisation avancé : traitement par lots](tutorial-lambda-resolvers.md#advanced-use-case-batching)

#### Modèle de mappage des demandes
<a name="lambda-resolvers-batching-request-template"></a>

Lorsque le traitement par lots est activé et que le modèle de mappage des demandes n'est pas fourni, AWS AppSync envoie une liste d'`Context`objets sous forme d'`BatchInvoke`opération directement à votre fonction Lambda.

#### Modèle de mappage des réponses
<a name="lambda-resolvers-batching-response-template"></a>

Lorsque le traitement par lots est activé et que le modèle de mappage des réponses n'est pas fourni, la logique de réponse est équivalente au modèle de mappage des réponses suivant :

```
#if( $context.result && $context.result.errorMessage )
      $utils.error($context.result.errorMessage, $context.result.errorType,
      $context.result.data)
#else
      $utils.toJson($context.result.data)
#end
```

La fonction Lambda doit renvoyer une liste de résultats dans le même ordre que la liste des `Context` objets envoyés. Vous pouvez renvoyer des erreurs individuelles en fournissant un `errorMessage` et `errorType` pour un résultat spécifique. Chaque résultat de la liste a le format suivant :

```
{
   "data" : { ... }, // your data
   "errorMessage" : { ... }, // optional, if included an error entry is added to the "errors" object in the AppSync response 
   "errorType" : { ... } // optional, the error type
}
```

**Note**  
Les autres champs de l'objet de résultat sont actuellement ignorés.

#### Gestion des erreurs liées à Lambda
<a name="lambda-resolvers-batching-error-handling"></a>

Vous pouvez renvoyer une erreur pour tous les résultats en lançant une exception ou une erreur dans votre fonction Lambda. Si la taille de la demande de charge utile ou de réponse pour votre demande de lot est trop importante, Lambda renvoie une erreur. Dans ce cas, vous devez envisager de réduire votre charge utile de réponse `maxBatchSize` ou de réduire sa taille.

Pour plus d'informations sur la gestion des erreurs individuelles, voir[Renvoi d'erreurs individuelles](tutorial-lambda-resolvers.md#returning-individual-errors).

#### Exemples de fonctions Lambda
<a name="sample-lambda-function"></a>

À l'aide du schéma ci-dessous, vous pouvez créer un résolveur Lambda direct pour le résolveur de `Post.relatedPosts` champs et activer le traitement par lots en définissant les paramètres ci-dessus : `maxBatchSize` `0`

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

type Query {
    getPost(id:ID!): Post
    allPosts: [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
    relatedPosts: [Post]
}
```

Dans la requête suivante, la fonction Lambda sera appelée avec des lots de demandes à résoudre : `relatedPosts`

```
query getAllPosts {
  allPosts {
    id
    relatedPosts {
      id
    }
  }
}
```

Une implémentation simple d'une fonction Lambda est fournie ci-dessous :

```
const posts = {
  1: {
    id: '1',
    title: 'First book',
    author: 'Author1',
    url: 'https://amazon.com/',
    content:
      'SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1 SAMPLE TEXT AUTHOR 1',
    ups: '100',
    downs: '10',
  },
  2: {
    id: '2',
    title: 'Second book',
    author: 'Author2',
    url: 'https://amazon.com',
    content: 'SAMPLE TEXT AUTHOR 2 SAMPLE TEXT AUTHOR 2 SAMPLE TEXT',
    ups: '100',
    downs: '10',
  },
  3: { id: '3', title: 'Third book', author: 'Author3', url: null, content: null, ups: null, downs: null },
  4: {
    id: '4',
    title: 'Fourth book',
    author: 'Author4',
    url: 'https://www.amazon.com/',
    content:
      'SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4 SAMPLE TEXT AUTHOR 4',
    ups: '1000',
    downs: '0',
  },
  5: {
    id: '5',
    title: 'Fifth book',
    author: 'Author5',
    url: 'https://www.amazon.com/',
    content: 'SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT AUTHOR 5 SAMPLE TEXT',
    ups: '50',
    downs: '0',
  },
}

const relatedPosts = {
  1: [posts['4']],
  2: [posts['3'], posts['5']],
  3: [posts['2'], posts['1']],
  4: [posts['2'], posts['1']],
  5: [],
}
exports.handler = async (event) => {
  console.log('event ->', event)
  // retrieve the ID of each post
  const ids = event.map((context) => context.source.id)
  // fetch the related posts for each post id
  const related = ids.map((id) => relatedPosts[id])

  // return the related posts; or an error if none were found
  return related.map((r) => {
    if (r.length > 0) {
      return { data: r }
    } else {
      return { data: null, errorMessage: 'Not found', errorType: 'ERROR' }
    }
  })
}
```