AWS AppSync riferimento al modello di mappatura del resolver per Lambda - AWS AppSync

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

AWS AppSync riferimento al modello di mappatura del resolver per Lambda

Nota

Ora supportiamo principalmente il runtime APPSYNC _JS e la relativa documentazione. Valuta la possibilità di utilizzare il runtime APPSYNC _JS e le relative guide qui.

Puoi usare AWS AppSync funzioni e resolver per richiamare le funzioni Lambda presenti nel tuo account. Puoi modellare i payload della richiesta e la risposta delle tue funzioni Lambda prima di restituirli ai tuoi clienti. Puoi anche utilizzare modelli di mappatura per fornire suggerimenti AWS AppSync sulla natura dell'operazione da richiamare. Questa sezione descrive i diversi modelli di mappatura per le operazioni Lambda supportate.

Richiedi un modello di mappatura

Il modello di mappatura delle richieste Lambda gestisce i campi relativi alla tua funzione Lambda:

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

Questa è la rappresentazione dello JSON schema del modello di mappatura delle richieste Lambda una volta risolto:

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

Ecco un esempio che utilizza un'invokeoperazione i cui dati di payload sono il getPost campo di uno schema GraphQL insieme ai suoi argomenti dal contesto:

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

L'intero documento di mappatura viene passato come input alla funzione Lambda in modo che l'esempio precedente abbia ora il seguente aspetto:

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

Versione

Comune a tutti i modelli di mappatura delle richieste, version definisce la versione utilizzata dal modello. versionÈ obbligatorio ed è un valore statico:

"version": "2018-05-29"

Operazione

L'origine dati Lambda consente di definire due operazioni sul operation campo: Invoke e. BatchInvoke L'Invokeoperazione consente di AWS AppSync sapere di chiamare la funzione Lambda per ogni resolver di campi GraphQL. BatchInvokeindica di eseguire AWS AppSync in batch le richieste per il campo GraphQL corrente. Il campo operation è obbligatorio.

InfattiInvoke, il modello di mappatura delle richieste risolte corrisponde al payload di input della funzione Lambda. Modifichiamo l'esempio precedente:

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

Questo problema viene risolto e passato alla funzione Lambda, che potrebbe assomigliare a questa:

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

InfattiBatchInvoke, il modello di mappatura viene applicato a tutti i risolutori di campi del batch. Per motivi di concisione, AWS AppSync unisce tutti i payload valori del modello di mappatura risolti in un elenco sotto un singolo oggetto corrispondente al modello di mappatura. Il modello di esempio seguente mostra l'unione:

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

Questo modello viene risolto nel documento di mappatura seguente:

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

Ogni elemento dell'payloadelenco corrisponde a un singolo elemento del batch. La funzione Lambda dovrebbe inoltre restituire una risposta a forma di elenco corrispondente all'ordine degli elementi inviati nella richiesta:

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

Payload

Il payload campo è un contenitore utilizzato per passare qualsiasi formato ben formato JSON alla funzione Lambda. Se il operation campo è impostato suBatchInvoke, AWS AppSync racchiude i payload valori esistenti in un elenco. Il campo payload è facoltativo.

Tipo di chiamata

L'origine dati Lambda consente di definire due tipi di invocazione: e. RequestResponse Event I tipi di invocazione sono sinonimi dei tipi di invocazione definiti in Lambda. API Il tipo di RequestResponse invocazione consente di AWS AppSync chiamare la funzione Lambda in modo sincrono per attendere una risposta. L'Eventinvocazione consente di richiamare la funzione Lambda in modo asincrono. Per ulteriori informazioni su come Lambda gestisce le richieste dei tipi di Event invocazione, consulta Invocazione asincrona. Il campo invocationType è facoltativo. Se questo campo non è incluso nella richiesta, verrà utilizzato per impostazione predefinita il tipo di invocazione. AWS AppSync RequestResponse

Per qualsiasi invocationType campo, la richiesta risolta corrisponde al payload di input della funzione Lambda. Modifichiamo l'esempio precedente:

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

Questo problema viene risolto e passato alla funzione Lambda, che potrebbe assomigliare a questa:

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

Quando l'BatchInvokeoperazione viene utilizzata insieme al campo del tipo di Event invocazione, AWS AppSync unisce il resolver di campo nello stesso modo menzionato sopra e la richiesta viene passata alla funzione Lambda come evento asincrono costituito da un elenco di valori. payload Ti consigliamo di disabilitare la memorizzazione nella cache dei resolver per i resolver di tipo di Event invocazione perché questi non verrebbero inviati a Lambda se si verificasse un problema nella cache.

Modello di mappatura delle risposte

Come con altre fonti di dati, la funzione Lambda invia una risposta a AWS AppSync che deve essere convertita in un tipo GraphQL.

Il risultato della funzione Lambda viene impostato sull'contextoggetto disponibile tramite la proprietà Velocity Template Language ()VTL. $context.result

Se la forma della risposta della funzione Lambda corrisponde esattamente alla forma del tipo GraphQL, puoi inoltrare la risposta usando il modello di mappatura della risposta seguente:

$util.toJson($context.result)

Non ci sono campi obbligatori né restrizioni relative alla forma che si applicano al modello di mappatura della risposta. Tuttavia, poiché GraphQL è un protocollo fortemente tipizzato, il modello di mappatura risolto deve corrispondere al tipo GraphQL previsto.

Risposta in batch della funzione Lambda

Se il operation campo è impostato suBatchInvoke, AWS AppSync si aspetta un elenco di elementi dalla funzione Lambda. Per mappare ogni risultato AWS AppSync all'elemento della richiesta originale, l'elenco delle risposte deve corrispondere per dimensioni e ordine. È valido avere null elementi nell'elenco delle risposte; $ctx.result è impostato di conseguenza su null.

Resolver Lambda diretti

Se desideri aggirare completamente l'uso dei modelli di mappatura, AWS AppSync puoi fornire un payload predefinito alla tua funzione Lambda e una risposta della funzione Lambda predefinita a un tipo GraphQL. Puoi scegliere di fornire un modello di richiesta, un modello di risposta o nessuno dei due e gestirlo di conseguenza. AWS AppSync

Modello di mappatura delle richieste Direct Lambda

Quando il modello di mappatura della richiesta non viene fornito, AWS AppSync invierà l'Contextoggetto direttamente alla funzione Lambda come Invoke operazione. Per ulteriori informazioni sulla struttura dell’oggetto Context, consulta AWS AppSync riferimento al contesto del modello di mappatura del resolver.

Modello di mappatura della risposta Direct Lambda

Quando il modello di mappatura delle risposte non viene fornito, AWS AppSync esegue una delle due operazioni dopo aver ricevuto la risposta della funzione Lambda. Se non hai fornito un modello di mappatura delle richieste o se hai fornito un modello di mappatura delle richieste con la versione2018-05-29, la risposta sarà equivalente al seguente modello di mappatura delle risposte:

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

Se hai fornito un modello con la versione2017-02-28, la logica di risposta funziona in modo equivalente al seguente modello di mappatura delle risposte:

$util.toJson($ctx.result)

Superficialmente, il bypass del modello di mappatura funziona in modo simile all'utilizzo di determinati modelli di mappatura, come mostrato negli esempi precedenti. Tuttavia, dietro le quinte, la valutazione dei modelli di mappatura viene completamente elusa. Poiché la fase di valutazione del modello viene ignorata, in alcuni scenari le applicazioni potrebbero subire un sovraccarico e una latenza inferiori durante la risposta rispetto a una funzione Lambda con un modello di mappatura delle risposte che deve essere valutato.

Gestione personalizzata degli errori nelle risposte di Direct Lambda Resolver

Puoi personalizzare le risposte agli errori delle funzioni Lambda richiamate dai Direct Lambda Resolver sollevando un'eccezione personalizzata. L'esempio seguente mostra come creare un'eccezione personalizzata utilizzando: JavaScript

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

Quando vengono sollevate eccezioni, i errorType e errorMessage sono rispettivamente l'errore personalizzato generato name e message l'errore personalizzato generato.

In caso errorType UnauthorizedException AWS AppSync affermativo, restituisce il messaggio predefinito ("You are not authorized to make this call.") anziché un messaggio personalizzato.

Il seguente frammento è un esempio di risposta GraphQL che dimostra una personalizzazione: errorType

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

Direct Lambda Resolver: batch abilitato

Puoi abilitare il batching per il tuo Direct Lambda Resolver maxBatchSize configurandolo sul tuo resolver. Quando maxBatchSize è impostato su un valore maggiore di quello 0 di un resolver Direct Lambda, AWS AppSync invia richieste in batch alla funzione Lambda con dimensioni fino a. maxBatchSize

L'impostazione maxBatchSize 0 su un resolver Direct Lambda disattiva il batch.

Per ulteriori informazioni su come funziona il batching con i resolver Lambda, consulta. Caso d'uso avanzato: batch

Richiedi un modello di mappatura

Quando il batching è abilitato e il modello di mappatura della richiesta non viene fornito, AWS AppSync invia un elenco di Context oggetti come BatchInvoke operazione direttamente alla funzione Lambda.

Modello di mappatura delle risposte

Quando il batching è abilitato e il modello di mappatura delle risposte non viene fornito, la logica di risposta è equivalente al seguente modello di mappatura delle risposte:

#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 funzione Lambda deve restituire un elenco di risultati nello stesso ordine dell'elenco degli Context oggetti inviati. È possibile restituire singoli errori fornendo un errorMessage e errorType per un risultato specifico. Ogni risultato dell'elenco ha il seguente formato:

{ "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 }
Nota

Gli altri campi dell'oggetto risultato sono attualmente ignorati.

Gestione degli errori da Lambda

Puoi restituire un errore per tutti i risultati generando un'eccezione o un errore nella tua funzione Lambda. Se la dimensione della richiesta di payload o della risposta per la richiesta batch è troppo grande, Lambda restituisce un errore. In tal caso, dovresti prendere in considerazione la possibilità di ridurre maxBatchSize o ridurre le dimensioni del payload di risposta.

Per informazioni sulla gestione dei singoli errori, vedereRestituzione di errori individuali.

Funzioni Lambda di esempio

Utilizzando lo schema seguente, puoi creare un Direct Lambda Resolver per il Post.relatedPosts field resolver e abilitare il batching impostando sopra: 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] }

Nella seguente query, la funzione Lambda verrà chiamata con batch di richieste da risolvere: relatedPosts

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

Di seguito viene fornita una semplice implementazione di una funzione Lambda:

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' } } }) }