View a markdown version of this page

AWS AppSync référence du modèle de mappage de résolveurs pour Lambda - AWS AppSync GraphQL

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 de résolveurs pour Lambda

Note

Nous prenons désormais en charge principalement le runtime APPSYNC_JS et sa documentation. Pensez à utiliser le moteur d'exécution APPSYNC_JS 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 invoquer les fonctions Lambda situées dans votre compte. Vous pouvez modifier 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 de demandes

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 schématique JSON du modèle de mappage de requêtes 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 tant qu'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

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

"version": "2018-05-29"

Opération

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

PourInvoke, le modèle de mappage des demandes résolues correspond à la charge utile en 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" } } }

PourBatchInvoke, 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 de lot. La fonction Lambda devrait également renvoyer une réponse sous forme de liste correspondant à l'ordre des éléments envoyés dans la requête :

[ { "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

Le payload champ est un conteneur utilisé pour transmettre tout JSON bien formé à la fonction Lambda. Si le operation champ est défini surBatchInvoke, AWS AppSync regroupe les payload valeurs existantes dans une liste. Le champ payload est facultatif.

Types d’invocation

La source de données Lambda vous permet de définir deux types d'invocation : RequestResponse et. Event Les types d'appel sont synonymes des types d'appel définis dans l'API Lambda. Le type RequestResponse d'invocation permet d' AWS AppSync appeler votre fonction Lambda de manière synchrone pour attendre une réponse. L'Eventinvocation vous permet d'invoquer votre fonction Lambda de manière asynchrone. Pour plus d'informations sur la façon dont Lambda gère les demandes de type d'Eventappel, consultez Invocation asynchrone. Le champ invocationType est facultatif. Si ce champ n'est pas inclus dans la demande, le type d'RequestResponseinvocation AWS AppSync sera utilisé par défaut.

Pour tous les invocationType champs, la demande résolue correspond à la charge utile en 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'BatchInvokeopération est utilisée conjointement avec le champ de type d'Eventinvocation, 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 la forme d'un événement asynchrone, sous la payload forme d'une liste de valeurs. Nous vous recommandons de désactiver la mise en cache des 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

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

Le résultat de la fonction Lambda est défini sur l'contextobjet 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

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

Résolveurs Lambda directs

Si vous souhaitez contourner 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

Lorsque le modèle de mappage de requêtes n'est pas fourni, l'Contextobjet AWS AppSync sera envoyé directement à votre fonction Lambda en tant qu'Invokeopé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.

Modèle de mappage de réponse Lambda direct

Lorsque le modèle de mappage des réponses n'est pas fourni, AWS AppSync effectue l'une des deux opérations suivantes à la réception de 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 version2018-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 version2017-02-28, la logique de réponse fonctionne de manière équivalente au modèle de mappage de réponse 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. Étant donné que l'étape d'évaluation du modèle est contournée, les applications peuvent subir moins de frais et de latence pendant la réponse dans certains scénarios par rapport à une fonction Lambda avec un modèle de mappage de réponse qui doit être évalué.

Gestion personnalisée des erreurs dans les réponses de Direct Lambda Resolver

Vous pouvez personnaliser les réponses aux erreurs à partir des fonctions Lambda que les résolveurs Lambda directs invoquent 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, le errorType et errorMessage est le name etmessage, respectivement, de l'erreur personnalisée qui est renvoyée.

Si errorType c'est le casUnauthorizedException, 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 : traitement par lots activé

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

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

Pour plus d'informations sur le fonctionnement du traitement par lots avec les résolveurs Lambda, consultez. Cas d'utilisation avancé : traitement par lots

Modèle de mappage de demandes

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'Contextobjets sous forme d'BatchInvokeopération directement à votre fonction Lambda.

Modèle de mappage des réponses

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 est au 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 provenant de Lambda

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 la réponse pour votre demande par lots est trop importante, Lambda renvoie une erreur. Dans ce cas, vous devriez 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, consultezRenvoi d'erreurs individuelles.

Exemples de fonctions Lambda

À 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 utilisant 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 requêtes à 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' } } }) }