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 guida alla programmazione dei modelli di mappatura dei resolver
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.
Questo è un tutorial in stile libro di cucina sulla programmazione con Apache Velocity Template Language () in. VTL AWS AppSync Se hai familiarità con altri linguaggi di programmazione come JavaScript C o Java, dovrebbe essere abbastanza semplice.
AWS AppSync usa VTL per tradurre le richieste GraphQL dei client in una richiesta alla tua fonte di dati. Inverte quindi il processo per tradurre la risposta dell'origine dati in risposta GraphQL. VTLè un linguaggio di template logico che consente di manipolare sia la richiesta che la risposta nel flusso standard di richiesta/risposta di un'applicazione Web, utilizzando tecniche come:
-
Valori predefiniti per nuove voci
-
Convalida e formattazione dell'input
-
Trasformazione e modellazione dei dati
-
Iterazione su elenchi, mappe e matrici per ottenere o modificare i valori
-
Applicazione di filtri/modifiche alle risposte in base all'identità dell'utente
-
Verifiche dell'autorizzazione complesse
Ad esempio, potresti voler eseguire una convalida del numero di telefono nel servizio su un argomento GraphQL o convertire un parametro di input in lettere maiuscole prima di archiviarlo in DynamoDB. O magari vuoi che i sistemi client forniscano un codice, come parte di un argomento GraphQL, di un JWT token claim o di un'HTTPintestazione, e rispondano con i dati solo se il codice corrisponde a una stringa specifica in un elenco. Questi sono tutti controlli logici che puoi eseguire con VTL in. AWS AppSync
VTLconsente di applicare la logica utilizzando tecniche di programmazione che potrebbero essere familiari. Tuttavia, è limitato all'esecuzione all'interno del flusso di richiesta/risposta standard per garantire che GraphQL API sia scalabile man mano che la base di utenti cresce. Poiché supporta AWS AppSync anche AWS Lambda come resolver, puoi scrivere funzioni Lambda nel tuo linguaggio di programmazione preferito (Node.js, Python, Go, Java, ecc.) se hai bisogno di maggiore flessibilità.
Installazione
Una tecnica comune per l'apprendimento di una lingua consiste nel stampare i risultati (ad esempio, console.log(variable)
in JavaScript) per vedere cosa succede. In questo tutorial mostreremo questa tecnica creando un semplice schema GraphQL e passando una mappa di valori a una funzione Lambda. La funzione Lambda stampa i valori e quindi risponde con questi. In questo modo, puoi comprendere il flusso di richiesta/risposta e osservare diverse tecniche di programmazione.
Per iniziare, crea lo schema GraphQL seguente:
type Query { get(id: ID, meta: String): Thing } type Thing { id: ID! title: String! meta: String } schema { query: Query }
Ora create la seguente AWS Lambda funzione, usando Node.js come linguaggio:
exports.handler = (event, context, callback) => { console.log('VTL details: ', event); callback(null, event); };
Nel riquadro Fonti dati della AWS AppSync console, aggiungi questa funzione Lambda come nuova origine dati. Torna alla pagina Schema della console e fai clic sul ATTACHpulsante a destra, accanto alla get(...):Thing
query. Per il modello di richiesta, scegli il modello esistente dal menu Invoke and forward arguments (Richiama e inoltra argomenti). Per il modello di risposta, scegli Return Lambda result (Restituisci risultato Lambda).
Apri Amazon CloudWatch Logs per la tua funzione Lambda in un'unica posizione e dalla scheda Queries della console, esegui AWS AppSync la seguente query GraphQL:
query test { get(id:123 meta:"testing"){ id meta } }
La risposta GraphQL deve contenere id:123
e meta:testing
, perché la funzione Lambda ne esegue di nuovo l'echoing. Dopo alcuni secondi, dovresti vedere anche un record in CloudWatch Logs con questi dettagli.
Variables
VTLutilizza riferimenti$
all'inizio e vengono create con la direttiva #set
:
#set($var = "a string")
Nelle variabili sono archiviati tipi simili di altri linguaggi con cui hai familiarità, ad esempio numeri, stringhe, matrici, elenchi e mappe. Potresti aver notato che un JSON payload viene inviato nel modello di richiesta predefinito per i resolver Lambda:
"payload": $util.toJson($context.arguments)
Ecco un paio di cose da notare: innanzitutto, AWS AppSync offre diverse funzioni utili per le operazioni più comuni. In questo esempio, $util.toJson
converte una variabile inJSON. In secondo luogo, la variabile $context.arguments
viene popolata automaticamente da una richiesta GraphQL come oggetto mappa. Puoi creare una nuova mappa in questo modo:
#set( $myMap = { "id": $context.arguments.id, "meta": "stuff", "upperMeta" : $context.arguments.meta.toUpperCase() } )
Hai ora creato una variabile denominata $myMap
, che include le chiavi id
, meta
e upperMeta
. Si verifica anche quanto segue:
-
id
viene popolato con una chiave dagli argomenti GraphQL. Ciò è comune quando VTL si acquisiscono argomenti dai client. -
meta
è codificato con un valore e mostra valori predefiniti. -
upperMeta
sta trasformando l'argomentometa
tramite un metodo.toUpperCase()
.
Inserisci il codice precedente all'inizio del modello di richiesta e modifica payload
in modo da usare la nuova variabile $myMap
:
"payload": $util.toJson($myMap)
Esegui la tua funzione Lambda e puoi vedere la modifica della risposta e questi dati nei CloudWatch log. Man mano che procediamo nelle altre fasi di questo tutorial, continueremo a popolare $myMap
per permetterti di eseguire test simili.
Puoi anche impostare proprietà nelle variabili. Potrebbero essere semplici stringhe, matrici o: JSON
#set($myMap.myProperty = "ABC") #set($myMap.arrProperty = ["Write", "Some", "GraphQL"]) #set($myMap.jsonProperty = { "AppSync" : "Offline and Realtime", "Cognito" : "AuthN and AuthZ" })
Riferimenti silenziosi
Poiché VTL è un linguaggio di template, per impostazione predefinita, ogni riferimento che gli fornirai farà un. .toString()
Se il riferimento non è definito, viene stampata l'effettiva rappresentazione del riferimento, come stringa. Per esempio:
#set($myValue = 5) ##Prints '5' $myValue ##Prints '$somethingelse' $somethingelse
Per risolvere questo problema, VTL utilizza una sintassi silenziosa o silenziosa, che indica al motore dei template di sopprimere questo comportamento. La sintassi è $!{}
. Ad esempio, se abbiamo leggermente modificato il codice precedente in modo da usare $!{somethingelse}
, la stampa sarà annullata:
#set($myValue = 5) ##Prints '5' $myValue ##Nothing prints out $!{somethingelse}
Metodi di chiamata
In un esempio precedente, abbiamo dimostrato come creare una variabile e contemporaneamente impostare valori. Ciò può essere eseguito in due passaggi, aggiungendo dati alla mappa come illustrato di seguito:
#set ($myMap = {}) #set ($myList = []) ##Nothing prints out $!{myMap.put("id", "first value")} ##Prints "first value" $!{myMap.put("id", "another value")} ##Prints true $!{myList.add("something")}
HOWEVERc'è qualcosa da sapere su questo comportamento. Benché la notazione $!{}
per i riferimenti invisibili permetta di chiamare metodi, come mostrato sopra, non eliminerà il valore restituito del metodo eseguito. Ecco perché nell'esempio sopra abbiamo osservato ##Prints "first value"
e ##Prints true
. In questo caso, possono verificarsi errori quando esegui l'iterazione di mappe o elenchi, ad esempio inserendo un valore quando esiste già una chiave, perché l'output aggiunge stringhe impreviste al modello in fase di valutazione.
La soluzione alternativa a questo problema consiste a volte nel chiamare i metodi usando una direttiva #set
e ignorando la variabile. Per esempio:
#set ($myMap = {}) #set($discard = $myMap.put("id", "first value"))
È possibile utilizzare questa tecnica nei modelli, in quanto impedisce la stampa di stringhe impreviste nel modello. AWS AppSync fornisce una comoda funzione alternativa che offre lo stesso comportamento in una notazione più succinta. In questo modo, puoi ignorare queste specifiche di implementazione. Puoi accedere a questa funzione in $util.quiet()
o nel relativo alias $util.qr()
. Per esempio:
#set ($myMap = {}) #set ($myList = []) ##Nothing prints out $util.quiet($myMap.put("id", "first value")) ##Nothing prints out $util.qr($myList.add("something"))
Stringhe
Come per tutti i linguaggi di programmazione, le stringhe possono essere difficili da gestire, in particolare quando vuoi crearle da variabili. Ci sono alcune cose comuni che emergono. VTL
Supponiamo di inserire dati come stringa in un'origine dati come DynamoDB, ma che siano compilati da una variabile, come un argomento GraphQL. Una stringa avrà virgolette doppie e per fare riferimento alla variabile in una stringa dovrai immettere semplicemente "${}"
(e non !
come per la notazione dei riferimenti invisibili
#set($firstname = "Jeff") $!{myMap.put("Firstname", "${firstname}")}
È possibile vederlo nei modelli di richiesta DynamoDB, ad "author": { "S" :
"${context.arguments.author}"}
esempio quando si utilizzano argomenti dei client GraphQL o per la generazione automatica di ID come. "id" : { "S" : "$util.autoId()"}
Di conseguenza, puoi fare riferimento a una variabile o al risultato di un metodo all'interno di una stringa per immettere i dati.
Puoi anche usare metodi pubblici della classe String
#set($bigstring = "This is a long string, I want to pull out everything after the comma") #set ($comma = $bigstring.indexOf(',')) #set ($comma = $comma +2) #set ($substring = $bigstring.substring($comma)) $util.qr($myMap.put("substring", "${substring}"))
Anche la concatenazione di stringhe è un'attività molto comune. Puoi eseguirla solo con riferimenti di variabile o con valori statici:
#set($s1 = "Hello") #set($s2 = " World") $util.qr($myMap.put("concat","$s1$s2")) $util.qr($myMap.put("concat2","Second $s1 World"))
Loop
Dopo avere creato variabili e chiamato metodi, puoi ora aggiungere la logica al codice. A differenza di altri linguaggi, VTL consente solo cicli, in cui il numero di iterazioni è predeterminato. Velocity non include do..while
. Questa progettazione garantisce che il processo di valutazione termini sempre e fornisce limiti di scalabilità durante l'esecuzione delle operazioni GraphQL.
I loop vengono creati con #foreach
e richiedono che venga specificata una variabile di loop e un oggetto iterabile , ad esempio una matrice, un elenco, una mappa o una raccolta. Un classico esempio di programmazione con un loop #foreach
è l'esecuzione di un loop di voci in una raccolta e la rispettiva stampa. Di conseguenza, in questo caso recupereremo le voci e quindi le aggiungeremo alla mappa:
#set($start = 0) #set($end = 5) #set($range = [$start..$end]) #foreach($i in $range) ##$util.qr($myMap.put($i, "abc")) ##$util.qr($myMap.put($i, $i.toString()+"foo")) ##Concat variable with string $util.qr($myMap.put($i, "${i}foo")) ##Reference a variable in a string with "${varname}" #end
Questo esempio mostra un paio di caratteristiche. La prima è l'uso di variabili con l'operatore di intervallo [..]
per creare un oggetto iterabile. Quindi ogni voce viene referenziata da una variabile $i
che puoi usare. Nell'esempio precedente noterai anche che i commenti sono contrassegnati da un doppio simbolo di cancelletto ##
. Questo mostra anche l'uso della variabile di loop in entrambi i valori o chiavi, nonché metodi diversi di concatenazione tramite stringhe.
Poiché $i
è un valore intero, puoi chiamare un metodo .toString()
. Per i tipi di GraphQLINT, questo può essere utile.
Puoi anche usare un operatore di intervallo direttamente, ad esempio:
#foreach($item in [1..5]) ... #end
Matrici
Finora avete manipolato una mappa, ma gli array sono comuni anche in. VTL Con le matrici, hai anche accesso ad alcuni metodo sottostanti, tra cui .isEmpty()
, .size()
, .set()
, .get()
e .add()
, mostrati di seguito:
#set($array = []) #set($idx = 0) ##adding elements $util.qr($array.add("element in array")) $util.qr($myMap.put("array", $array[$idx])) ##initialize array vals on create #set($arr2 = [42, "a string", 21, "test"]) $util.qr($myMap.put("arr2", $arr2[$idx])) $util.qr($myMap.put("isEmpty", $array.isEmpty())) ##isEmpty == false $util.qr($myMap.put("size", $array.size())) ##Get and set items in an array $util.qr($myMap.put("set", $array.set(0, 'changing array value'))) $util.qr($myMap.put("get", $array.get(0)))
L'esempio precedente utilizzava la notazione dell'indice di matrice per recuperare un elemento con. arr2[$idx]
Puoi cercare in base al nome da un dizionario/mappa in un modo simile:
#set($result = { "Author" : "Nadia", "Topic" : "GraphQL" }) $util.qr($myMap.put("Author", $result["Author"]))
Questo approccio è molto comune quando filtri i risultati restituiti da origini dati nei modelli di risposta usando condizionali.
Controlli condizionali
La sezione precedente #foreach
mostrava alcuni esempi di utilizzo della logica per trasformare i dati. VTL Puoi anche applicare controlli condizionali per valutare i dati in fase di esecuzione:
#if(!$array.isEmpty()) $util.qr($myMap.put("ifCheck", "Array not empty")) #else $util.qr($myMap.put("ifCheck", "Your array is empty")) #end
Il controllo #if()
di un'espressione booleana mostrato sopra è valido, ma puoi anche usare operatori e #elseif()
per la definizione di diramazioni:
#if ($arr2.size() == 0) $util.qr($myMap.put("elseIfCheck", "You forgot to put anything into this array!")) #elseif ($arr2.size() == 1) $util.qr($myMap.put("elseIfCheck", "Good start but please add more stuff")) #else $util.qr($myMap.put("elseIfCheck", "Good job!")) #end
Questi due esempi hanno mostrato una negazione (!) e un'uguaglianza (==). Possiamo usare anche ||, &&, >, <, >=, <= e !=.
#set($T = true) #set($F = false) #if ($T || $F) $util.qr($myMap.put("OR", "TRUE")) #end #if ($T && $F) $util.qr($myMap.put("AND", "TRUE")) #end
Nota: solo Boolean.FALSE
e null
sono considerati valori false nei condizionali. Zero (0) e le stringhe vuote ("") non equivalgono a false.
Operatori
Nessun linguaggio di programmazione sarebbe completo senza alcuni operatori per l'esecuzione di operazioni matematiche. Ecco alcuni esempi per iniziare:
#set($x = 5) #set($y = 7) #set($z = $x + $y) #set($x-y = $x - $y) #set($xy = $x * $y) #set($xDIVy = $x / $y) #set($xMODy = $x % $y) $util.qr($myMap.put("z", $z)) $util.qr($myMap.put("x-y", $x-y)) $util.qr($myMap.put("x*y", $xy)) $util.qr($myMap.put("x/y", $xDIVy)) $util.qr($myMap.put("x|y", $xMODy))
Utilizzo congiunto di loop e condizionali
È molto comune quando si trasformano i datiVTL, ad esempio prima di scrivere o leggere da un'origine dati, ripetere gli oggetti e quindi eseguire controlli prima di eseguire un'azione. La combinazione di alcuni degli strumenti mostrati nelle sezioni precedenti offre molte funzionalità. Un'informazione utile di cui tenere conto è che #foreach
fornisce automaticamente un oggetto .count
in ogni voce:
#foreach ($item in $arr2) #set($idx = "item" + $foreach.count) $util.qr($myMap.put($idx, $item)) #end
Ad esempio, se vuoi semplicemente recuperare valori da una mappa al di sotto di una determinata dimensione. L'uso del conteggio insieme a condizionali e all'istruzione #break
ti permette di eseguire questa operazione:
#set($hashmap = { "DynamoDB" : "https://aws.amazon.com/dynamodb/", "Amplify" : "https://github.com/aws/aws-amplify", "DynamoDB2" : "https://aws.amazon.com/dynamodb/", "Amplify2" : "https://github.com/aws/aws-amplify" }) #foreach ($key in $hashmap.keySet()) #if($foreach.count > 2) #break #end $util.qr($myMap.put($key, $hashmap.get($key))) #end
Il loop #foreach
precedente viene iterato con .keySet()
, che puoi usare nelle mappe. In questo modo, puoi accedere per ottenere $key
e fare riferimento al valore con .get($key)
. Gli argomenti GraphQL dei client in AWS AppSync vengono archiviati come mappa. Inoltre possono essere iterati tramite .entrySet()
, che ti permette quindi di accedere a entrambi i valori e le chiavi come Set e popolare altre variabili o eseguire controlli condizionali complessi, come la convalida o la trasformazione dell'input:
#foreach( $entry in $context.arguments.entrySet() ) #if ($entry.key == "XYZ" && $entry.value == "BAD") #set($myvar = "...") #else #break #end #end
Altri esempi comuni sono l'inserimento automatico di informazioni predefinite, come le versioni iniziali degli oggetti durante la sincronizzazione dei dati (molto importante nella risoluzione dei conflitti) o il proprietario predefinito di un oggetto per i controlli di autorizzazione. Mary ha creato questo post sul blog, quindi:
#set($myMap.owner ="Mary") #set($myMap.defaultOwners = ["Admins", "Editors"])
Context
Ora che hai più dimestichezza con l'esecuzione di controlli logici nei AWS AppSync resolverVTL, dai un'occhiata all'oggetto context:
$util.qr($myMap.put("context", $context))
Questo oggetto contiene tutte le informazioni cui puoi accedere nella richiesta GraphQL. Per una spiegazione dettagliata, consulta le informazioni di riferimento sull'oggetto.
Filtraggio
Finora in questo tutorial tutte le informazioni della funzione Lambda sono state restituite alla query GraphQL con una trasformazione molto semplice: JSON
$util.toJson($context.result)
La VTL logica è altrettanto potente quando si ottengono risposte da una fonte di dati, specialmente quando si eseguono controlli di autorizzazione sulle risorse. Osserviamo alcuni esempi. Prima di tutto, prova a modificare il modello di risposta in questo modo:
#set($data = { "id" : "456", "meta" : "Valid Response" }) $util.toJson($data)
Indipendentemente da quanto avviene con l'operazione GraphQL, al client vengono restituiti valori hardcoded. Puoi modificare leggermente questo comportamento in modo che il campo meta
venga popolato dalla risposta Lambda, impostata in precedenza nel tutorial nel valore elseIfCheck
quando abbiamo presentato i condizionali:
#set($data = { "id" : "456" }) #foreach($item in $context.result.entrySet()) #if($item.key == "elseIfCheck") $util.qr($data.put("meta", $item.value)) #end #end $util.toJson($data)
Poiché $context.result
è una mappa, puoi usare entrySet()
per eseguire la logica su uno dei valori o delle chiavi restituiti. Poiché $context.identity
contiene informazioni sull'utente che ha eseguito l'operazione GraphQL, se restituisci informazioni di autorizzazione dall'origine dati, puoi scegliere di restituire a un utente tutti i dati, alcuni o nessuno in base alla logica. Modifica il modello di risposta in modo che sia simile al seguente:
#if($context.result["id"] == 123) $util.toJson($context.result) #else $util.unauthorized() #end
Se esegui la query GraphQL, i dati verranno restituiti normalmente. Tuttavia, se modifichi l'argomento id in un valore diverso da 123 (query test { get(id:456
meta:"badrequest"){} }
), riceverai un messaggio di autorizzazione non concessa.
Puoi trovare altri esempi di scenari di autorizzazione nella sezione dei casi d'uso di autorizzazione.
Esempio di modello
Se hai seguito interamente il tutorial, avrai creato questo modello passo dopo passo. Se non lo hai fatto, lo includiamo di seguito per copiarlo per il test.
Modello di richiesta
#set( $myMap = { "id": $context.arguments.id, "meta": "stuff", "upperMeta" : "$context.arguments.meta.toUpperCase()" } ) ##This is how you would do it in two steps with a "quiet reference" and you can use it for invoking methods, such as .put() to add items to a Map #set ($myMap2 = {}) $util.qr($myMap2.put("id", "first value")) ## Properties are created with a dot notation #set($myMap.myProperty = "ABC") #set($myMap.arrProperty = ["Write", "Some", "GraphQL"]) #set($myMap.jsonProperty = { "AppSync" : "Offline and Realtime", "Cognito" : "AuthN and AuthZ" }) ##When you are inside a string and just have ${} without ! it means stuff inside curly braces are a reference #set($firstname = "Jeff") $util.qr($myMap.put("Firstname", "${firstname}")) #set($bigstring = "This is a long string, I want to pull out everything after the comma") #set ($comma = $bigstring.indexOf(',')) #set ($comma = $comma +2) #set ($substring = $bigstring.substring($comma)) $util.qr($myMap.put("substring", "${substring}")) ##Classic for-each loop over N items: #set($start = 0) #set($end = 5) #set($range = [$start..$end]) #foreach($i in $range) ##Can also use range operator directly like #foreach($item in [1...5]) ##$util.qr($myMap.put($i, "abc")) ##$util.qr($myMap.put($i, $i.toString()+"foo")) ##Concat variable with string $util.qr($myMap.put($i, "${i}foo")) ##Reference a variable in a string with "${varname)" #end ##Operators don't work #set($x = 5) #set($y = 7) #set($z = $x + $y) #set($x-y = $x - $y) #set($xy = $x * $y) #set($xDIVy = $x / $y) #set($xMODy = $x % $y) $util.qr($myMap.put("z", $z)) $util.qr($myMap.put("x-y", $x-y)) $util.qr($myMap.put("x*y", $xy)) $util.qr($myMap.put("x/y", $xDIVy)) $util.qr($myMap.put("x|y", $xMODy)) ##arrays #set($array = ["first"]) #set($idx = 0) $util.qr($myMap.put("array", $array[$idx])) ##initialize array vals on create #set($arr2 = [42, "a string", 21, "test"]) $util.qr($myMap.put("arr2", $arr2[$idx])) $util.qr($myMap.put("isEmpty", $array.isEmpty())) ##Returns false $util.qr($myMap.put("size", $array.size())) ##Get and set items in an array $util.qr($myMap.put("set", $array.set(0, 'changing array value'))) $util.qr($myMap.put("get", $array.get(0))) ##Lookup by name from a Map/dictionary in a similar way: #set($result = { "Author" : "Nadia", "Topic" : "GraphQL" }) $util.qr($myMap.put("Author", $result["Author"])) ##Conditional examples #if(!$array.isEmpty()) $util.qr($myMap.put("ifCheck", "Array not empty")) #else $util.qr($myMap.put("ifCheck", "Your array is empty")) #end #if ($arr2.size() == 0) $util.qr($myMap.put("elseIfCheck", "You forgot to put anything into this array!")) #elseif ($arr2.size() == 1) $util.qr($myMap.put("elseIfCheck", "Good start but please add more stuff")) #else $util.qr($myMap.put("elseIfCheck", "Good job!")) #end ##Above showed negation(!) and equality (==), we can also use OR, AND, >, <, >=, <=, and != #set($T = true) #set($F = false) #if ($T || $F) $util.qr($myMap.put("OR", "TRUE")) #end #if ($T && $F) $util.qr($myMap.put("AND", "TRUE")) #end ##Using the foreach loop counter - $foreach.count #foreach ($item in $arr2) #set($idx = "item" + $foreach.count) $util.qr($myMap.put($idx, $item)) #end ##Using a Map and plucking out keys/vals #set($hashmap = { "DynamoDB" : "https://aws.amazon.com/dynamodb/", "Amplify" : "https://github.com/aws/aws-amplify", "DynamoDB2" : "https://aws.amazon.com/dynamodb/", "Amplify2" : "https://github.com/aws/aws-amplify" }) #foreach ($key in $hashmap.keySet()) #if($foreach.count > 2) #break #end $util.qr($myMap.put($key, $hashmap.get($key))) #end ##concatenate strings #set($s1 = "Hello") #set($s2 = " World") $util.qr($myMap.put("concat","$s1$s2")) $util.qr($myMap.put("concat2","Second $s1 World")) $util.qr($myMap.put("context", $context)) { "version" : "2017-02-28", "operation": "Invoke", "payload": $util.toJson($myMap) }
Modello di risposta
#set($data = { "id" : "456" }) #foreach($item in $context.result.entrySet()) ##$context.result is a MAP so we use entrySet() #if($item.key == "ifCheck") $util.qr($data.put("meta", "$item.value")) #end #end ##Uncomment this out if you want to test and remove the below #if check ##$util.toJson($data) #if($context.result["id"] == 123) $util.toJson($context.result) #else $util.unauthorized() #end