nota
Ahora admitimos de forma básica el tiempo de ejecución APPSYNC_JS y su documentación. Considere la opción de utilizar el tiempo de ejecución APPSYNC_JS y sus guías aquí.
En este tutorial se muestra cómo puede aprovechar sus tablas de Amazon DynamoDB en AWS AppSync y conectarlas a una API de GraphQL.
Puede hacer que AWS AppSync aprovisione recursos de DynamoDB en su nombre. O bien, si lo prefiere, puede conectar las tablas existentes a un esquema de GraphQL creando un origen de datos y un solucionador. En cualquier caso, podrá leer y escribir en la base de datos de DynamoDB a través de instrucciones de GraphQL y suscribirse a datos en tiempo real.
Hay que realizar una serie de pasos de configuración específicos para que las instrucciones de GraphQL se traduzcan a operaciones de DynamoDB y que, a su vez, las respuestas se traduzcan de nuevo a GraphQL. En este tutorial se describe el proceso de configuración a través de varios escenarios y patrones de acceso a datos del mundo real.
Configuración de las tablas de DynamoDB
Para comenzar este tutorial, primero debe seguir los pasos que se indican a continuación para aprovisionar recursos de AWS.
-
Aprovisione recursos de AWS mediante la siguiente plantilla de AWS CloudFormation en 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
Como alternativa, puede iniciar la siguiente pila de AWS CloudFormation en la región EE. UU. Oeste 2 (Oregón) de su cuenta de AWS.
Así se crea lo siguiente:
-
Una tabla de DynamoDB llamada
AppSyncTutorial-Post
que contendrá datos dePost
. -
Un rol de IAM y una política administrada de IAM asociada para que AWS AppSync pueda interactuar con la tabla
Post
.
-
-
Para ver más información acerca de la pila y de los recursos creados, ejecute el siguiente comando de la CLI:
aws cloudformation describe-stacks --stack-name AWSAppSyncTutorialForAmazonDynamoDB
-
Para eliminar los recursos más adelante, puede ejecutar lo siguiente:
aws cloudformation delete-stack --stack-name AWSAppSyncTutorialForAmazonDynamoDB
Creación de la API de GraphQL
Para crear la API de GraphQL en AWS AppSync:
-
Inicie sesión en la AWS Management Console y abra la consola de AppSync
. -
En el Panel de API, elija Crear API.
-
-
En la ventana Personalice su API o impórtela desde Amazon DynamoDB, seleccione Crear desde cero.
-
Seleccione Comenzar a la derecha de la misma ventana.
-
-
En el campo Nombre de la API, establezca el nombre de la API en
AWSAppSyncTutorial
. -
Seleccione Crear.
La consola de AWS AppSync crea una nueva API de GraphQL automáticamente utilizando el modo de autenticación de clave de API. Puede utilizar la consola para configurar el resto de la API de GraphQL y ejecutar consultas en ella durante el resto de este tutorial.
Definición de una API de publicación básica
Ahora que ha creado una API de GraphQL en AWS AppSync, puede configurar un esquema básico que permita la creación, recuperación y eliminación básica de datos de publicaciones.
-
Inicie sesión en la AWS Management Console y abra la consola de AppSync
. -
En el Panel de API, elija la API que ha creado.
-
-
En la barra lateral, seleccione Esquema.
-
En la página Esquema, sustituya el contenido por el código siguiente:
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! }
-
-
Seleccione Guardar.
Este esquema define un tipo Post
y las operaciones para agregar y obtener objetos Post
.
Configuración del origen de datos para las tablas de DynamoDB
A continuación, vincule las consultas y las mutaciones definidas en el esquema a la tabla AppSyncTutorial-Post
de DynamoDB.
En primer lugar, AWS AppSync debe conocer las tablas. Para ello, configure un origen de datos en AWS AppSync:
-
Inicie sesión en la AWS Management Console y abra la consola de AppSync
. -
En el panel de API, seleccione su API de GraphQL.
-
En la barra lateral, seleccione Origen de datos.
-
-
Elija Crear origen de datos.
-
En Nombre de origen de datos, escriba
PostDynamoDBTable
. -
En Tipo de origen de datos, elija Tabla de Amazon DynamoDB.
-
En Región, elija US-WEST-2.
-
En Nombre de tabla, elija la tabla de DynamoDB AppSyncTutorial-Post.
-
Cree un nuevo rol de IAM (recomendado) o elija un rol existente que tenga el permiso de IAM
lambda:invokeFunction
. Los roles existentes necesitan una política de confianza, tal y como se explica en la sección Asociar un origen de datos.El siguiente es un ejemplo de política de IAM que tiene los permisos necesarios para llevar a cabo operaciones en el recurso:
{ "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:*" ] } ] }
-
-
Seleccione Crear.
Configuración del solucionador addPost (PutItem de DynamoDB)
Una vez que AWS AppSync conoce la tabla de DynamoDB, puede vincularla a consultas y mutaciones individuales mediante la definición de solucionadores. El primer solucionador que va a crear es addPost
, que le permite crear una publicación en la tabla AppSyncTutorial-Post
de DynamoDB.
Un solucionador tiene los siguientes componentes:
-
La ubicación en el esquema de GraphQL donde se asocia el solucionador. En este caso configuramos en el campo
addPost
un solucionador de tipoMutation
. El solucionador se invocará cuando el intermediario llame amutation { addPost(...){...} }
. -
El origen de datos que se va a utilizar para el solucionador. En este caso, queremos utilizar el origen de datos
PostDynamoDBTable
definido anteriormente para poder agregar entradas en la tablaAppSyncTutorial-Post
de DynamoDB. -
La plantilla de mapeo de solicitudes. El objetivo de la plantilla de mapeo de solicitudes es tomar la solicitud entrante del intermediario y convertirla en instrucciones que AWS AppSync ejecuta en DynamoDB.
-
La plantilla de mapeo de respuestas. El cometido de la plantilla de mapeo de respuesta es tomar la respuesta de DynamoDB y traducirla de nuevo a algo que GraphQL espera. Esto resulta útil si la forma de los datos en DynamoDB es diferente del tipo
Post
en GraphQL. Como este caso sí tienen la misma forma, solo hay que transmitir los datos.
Para configurar el solucionador de :
-
Inicie sesión en la AWS Management Console y abra la consola de AppSync
. -
En el panel de API, seleccione su API de GraphQL.
-
En la barra lateral, seleccione Origen de datos.
-
-
Elija Crear origen de datos.
-
En Nombre de origen de datos, escriba
PostDynamoDBTable
. -
En Tipo de origen de datos, elija Tabla de Amazon DynamoDB.
-
En Región, elija US-WEST-2.
-
En Nombre de tabla, elija la tabla de DynamoDB AppSyncTutorial-Post.
-
Cree un nuevo rol de IAM (recomendado) o elija un rol existente que tenga el permiso de IAM
lambda:invokeFunction
. Los roles existentes necesitan una política de confianza, tal y como se explica en la sección Asociar un origen de datos.El siguiente es un ejemplo de política de IAM que tiene los permisos necesarios para llevar a cabo operaciones en el recurso:
{ "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:*" ] } ] }
-
-
Seleccione Crear.
-
Elija la pestaña Schema (Esquema).
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo addPost en el tipo Mutation y, a continuación, seleccione Attach (Asociar).
-
En el menú Acción, seleccione Actualizar tiempo de ejecución y, a continuación, elija Solucionador de unidades (solo VTL).
-
En Data source name (Nombre del tipo de datos), elija PostDynamoDBTable.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), pegue lo siguiente:
{ "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 } } }
Nota: se especifica un tipo para todas las claves y valores de atributos. Por ejemplo, puede establecer el campo
author
como{ "S" : "${context.arguments.author}" }
. La parteS
indica a AWS AppSync y a DynamoDB que el valor será una cadena. El valor real se rellena con el argumentoauthor
. Del mismo modo, el campoversion
es numérico, ya que utilizaN
para el tipo. Por último, también inicializamos los camposups
,downs
yversion
.En este tutorial, especificó que el tipo
ID!
de GraphQL, que indexa el nuevo elemento que se inserta en DynamoDB, forma parte de los argumentos del cliente. AWS AppSync incluye una utilidad para la generación automática de identificadores denominada$utils.autoId()
que también podría haber utilizado con el formato"id" : { "S" : "${$utils.autoId()}" }
. Así bastaría con excluirid: ID!
de la definición del esquema deaddPost()
y se insertaría de forma automática. No utilizará esta técnica en este tutorial, pero debe considerarla, ya que se trata de una práctica recomendada a la hora de escribir en tablas de DynamoDB.Para obtener más información acerca de las plantillas de mapeo, consulte la sección Información general de plantillas de mapeo de solucionador. Para obtener más información sobre el mapeo de solicitudes GetItem, consulte la documentación de referencia de GetItem. Para obtener más información sobre los tipos, consulte la documentación de referencia del Sistema de tipos (mapeos de solicitud).
-
En Configure the response mapping template (Configurar la plantilla de mapeo de respuesta), pegue lo siguiente:
$utils.toJson($context.result)
Nota: Debido a que la forma de los datos de la tabla
AppSyncTutorial-Post
coincide exactamente con la forma del tipoPost
de GraphQL, la plantilla de mapeo de respuesta se limita a pasar directamente los resultados. Observe que todos los ejemplos de este tutorial utilizan la misma plantilla de mapeo de respuesta, de manera que solo tiene que crear un archivo. -
Seleccione Guardar.
Llame a la API para añadir una publicación
Ahora que el solucionador está configurado, AWS AppSync puede convertir una mutación addPost
entrante en una operación PutItem de DynamoDB. Ahora puede ejecutar una mutación para incluir datos en la tabla.
-
Seleccione la pestaña Queries (Consultas).
-
En el panel Queries (Consultas), pegue la mutación siguiente:
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 } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
Los resultados de la publicación que acaba de crear deben aparecer en el panel de resultados a la derecha del panel de consultas. Debería parecerse a lo que sigue:
{ "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 } } }
Esto es lo que ha ocurrido:
-
AWS AppSync ha recibido una solicitud de mutación
addPost
. -
AWS AppSync ha aceptado la solicitud y la plantilla de mapeo de solicitudes, y ha generado un documento de mapeo de solicitudes. Esto habrá tenido el siguiente aspecto:
{ "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 ha utilizado el documento de mapeo de solicitudes para generar y ejecutar una solicitud
PutItem
de DynamoDB. -
AWS AppSync ha tomado los resultados de la solicitud
PutItem
y los ha convertido de nuevo en tipos de 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 }
-
Después los ha pasado a través del documento de mapeo de respuesta, que se ha limitado a transferirlos sin cambios.
-
Por fin ha devuelto el objeto recién creado en la respuesta de GraphQL.
Configuración del solucionador getPost (GetItem de DynamoDB)
Ahora que puede añadir datos a la tabla de DynamoDB AppSyncTutorial-Post
, tiene que configurar la consulta getPost
para poder recuperar los datos de la tabla AppSyncTutorial-Post
. Para ello, tiene que configurar otro solucionador.
-
Elija la pestaña Schema (Esquema).
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo getPost en el tipo Query y, a continuación, seleccione Attach (Asociar).
-
En el menú Acción, seleccione Actualizar tiempo de ejecución y, a continuación, elija Solucionador de unidades (solo VTL).
-
En Data source name (Nombre del tipo de datos), elija PostDynamoDBTable.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), pegue lo siguiente:
{ "version" : "2017-02-28", "operation" : "GetItem", "key" : { "id" : $util.dynamodb.toDynamoDBJson($ctx.args.id) } }
-
En Configure the response mapping template (Configurar la plantilla de mapeo de respuesta), pegue lo siguiente:
$utils.toJson($context.result)
-
Seleccione Guardar.
Llame a la API para obtener una publicación
Ahora que ya está configurado el solucionador, AWS AppSync ya sabe cómo convertir una consulta getPost
entrante en una operación GetItem
de DynamoDB. Ahora puede ejecutar una consulta para recuperar la publicación que ha creado anteriormente.
-
Seleccione la pestaña Queries (Consultas).
-
En el panel Queries (Consultas), pegue lo siguiente:
query getPost { getPost(id:123) { id author title content url ups downs version } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
La publicación obtenida de DynamoDB debe aparecer en el panel de resultados a la derecha del panel de consultas. Debería parecerse a lo que sigue:
{ "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 } } }
Esto es lo que ha ocurrido:
-
AWS AppSync ha recibido una solicitud de consulta
getPost
. -
AWS AppSync ha aceptado la solicitud y la plantilla de mapeo de solicitudes, y ha generado un documento de mapeo de solicitudes. Esto habrá tenido el siguiente aspecto:
{ "version" : "2017-02-28", "operation" : "GetItem", "key" : { "id" : { "S" : "123" } } }
-
AWS AppSync ha utilizado el documento de mapeo de solicitudes para generar y ejecutar una solicitud GetItem de DynamoDB.
-
AWS AppSync ha tomado los resultados de la solicitud
GetItem
y los ha convertido de nuevo en tipos de 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 }
-
Después los ha pasado a través del documento de mapeo de respuesta, que se ha limitado a transferirlos sin cambios.
-
Entonces ha devuelto el objeto recuperado en la respuesta.
Como alternativa, vamos a tomar el siguiente ejemplo:
query getPost {
getPost(id:123) {
id
author
title
}
}
Si la consulta getPost
solo necesita las letras id
, author
y title
, puede cambiar la plantilla de mapeo de solicitudes para utilizar expresiones de proyección que especifiquen únicamente los atributos que desee de la tabla de DynamoDB y evitar la transferencia innecesaria de datos de DynamoDB a AWS AppSync. Por ejemplo, la plantilla de mapeo de solicitudes puede tener un aspecto similar al siguiente fragmento:
{
"version" : "2017-02-28",
"operation" : "GetItem",
"key" : {
"id" : $util.dynamodb.toDynamoDBJson($ctx.args.id)
},
"projection" : {
"expression" : "#author, id, title",
"expressionNames" : { "#author" : "author"}
}
}
Cree una mutación updatePost (UpdateItem de DynamoDB)
De momento ya sabe crear y recuperar objetos Post
en DynamoDB. A continuación va a configurar una nueva mutación que permite actualizar objetos. Para ello, utilizará la operación UpdateItem de DynamoDB.
-
Elija la pestaña Schema (Esquema).
-
En el panel Schema (Esquema) modifique el tipo
Mutation
para agregar una nueva mutaciónupdatePost
de este modo:type Mutation { updatePost( id: ID!, author: String!, title: String!, content: String!, url: String! ): Post addPost( author: String! title: String! content: String! url: String! ): Post! }
-
Seleccione Guardar.
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo updatePost recién creado en el tipo Mutation y, a continuación, elija Attach (Asociar).
-
En el menú Acción, seleccione Actualizar tiempo de ejecución y, a continuación, elija Solucionador de unidades (solo VTL).
-
En Data source name (Nombre del tipo de datos), elija PostDynamoDBTable.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), pegue lo siguiente:
{ "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 } } } }
Nota: Este solucionador utiliza la operación UpdateItem de DynamoDB, que difiere bastante de la operación PutItem. En lugar de escribir el elemento completo, solo pide a DynamoDB que actualice determinados atributos. Esto se consigue mediante expresiones de actualización de DynamoDB. La expresión en sí se especifica en el campo
expression
de la secciónupdate
. Indica que se deben establecer los atributosauthor
,title
,content
y URL, y a continuación incrementar el campoversion
. Los valores empleados no aparecen en la expresión en sí, que contiene marcadores de posición con nombres que comienzan con dos puntos y que luego se definen en el campoexpressionValues
. Por último, DynamoDB tiene palabras reservadas que no pueden aparecer en laexpression
. Por ejemplo,url
es una palabra reservada, por lo que para actualizar el campourl
, puede utilizar marcadores de posición de nombre y definirlos en el campoexpressionNames
.Para obtener más información acerca del mapeo de la solicitud
UpdateItem
, consulte la documentación de referencia de UpdateItem. Para obtener más información sobre el modo de escribir expresiones de actualización, consulte la documentación de DynamoDB UpdateExpressions. -
En Configure the response mapping template (Configurar la plantilla de mapeo de respuesta), pegue lo siguiente:
$utils.toJson($context.result)
Llame a la API para actualizar una publicación
Ahora que ya está configurado el solucionador, AWS AppSync ya sabe cómo convertir una mutación update
entrante en una operación Update
de DynamoDB. Ahora puede ejecutar una mutación para actualizar el elemento que escribió anteriormente.
-
Seleccione la pestaña Queries (Consultas).
-
En el panel Queries (Consultas), pegue la mutación siguiente. También tendrá que actualizar el argumento
id
con el valor que anotó anteriormente.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 } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
La publicación actualizada en DynamoDB debería aparecer en el panel de resultados a la derecha del panel de consultas. Debería parecerse a lo que sigue:
{ "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 } } }
En este ejemplo, los campos downs
y ups
no se han modificado, porque la plantilla de mapeo de solicitudes no ha pedido a AWS AppSync ni a DynamoDB que hagan nada con esos campos. Además, el campo version
se ha incrementado en 1, ya que pedimos a AWS AppSync y DynamoDB que sumaran 1 al campo version
.
Modificación del solucionador updatePost (UpdateItem en DynamoDB)
Se trata de un buen comienzo para la mutación updatePost
, pero tiene dos inconvenientes:
-
Aunque solo desee actualizar un campo, tiene que actualizar todos.
-
Si dos personas modifican el objeto a la vez información podría perderse información.
Para solucionar estos problemas, va a modificar la mutación updatePost
de manera que únicamente modifique los argumentos que se han especificado en la solicitud, y también va a agregar una condición a la operación UpdateItem
.
-
Elija la pestaña Schema (Esquema).
-
En el panel Schema (Esquema), modifique el campo
updatePost
del tipoMutation
para eliminar los signos de admiración de los argumentosauthor
,title
,content
yurl
, asegurándose de dejar sin cambios el campoid
. Esto los convertirá en argumentos opcionales. Además, añada un nuevo argumentoexpectedVersion
obligatorio.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! }
-
Seleccione Guardar.
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo updatePost en el tipo Mutation.
-
Elija PostDynamoDBTable para abrir el solucionador existente.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), modifique la plantilla de mapeo de solicitud de este modo:
{ "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) } } }
-
Seleccione Guardar.
Esta plantilla es uno de los ejemplos más complejos. Demuestra la eficacia y flexibilidad de las plantillas de mapeo. Itera por todos los argumentos, saltando id
y expectedVersion
. Si el argumento tiene un valor, solicita a AWS AppSync y DynamoDB que actualice en el objeto en DynamoDB. Si el atributo tiene el valor nulo, solicita a AWS AppSync y DynamoDB que lo elimine del objeto publicación. Si no se ha especificado algún argumento, lo dejará como está. También incrementa el campo version
.
También hay una nueva sección condition
. Una expresión de condición le permite indicar a AWS AppSync y DynamoDB que la solicitud debe ejecutarse o no en función del estado del objeto que ya se encuentra en DynamoDB antes de efectuar la operación. En este caso, solo quiere que la solicitud UpdateItem
se realice si el campo version
del elemento que hay en DynamoDB coincide exactamente con el argumento expectedVersion
.
Si desea más información sobre las expresiones de condición, consulte la documentación de referencia Expresiones de condición.
Llame a la API para actualizar una publicación
Vamos a intentar actualizar el objeto Post
con el nuevo solucionador:
-
Seleccione la pestaña Queries (Consultas).
-
En el panel Queries (Consultas), pegue la mutación siguiente. También tendrá que actualizar el argumento
id
con el valor que anotó anteriormente.mutation updatePost { updatePost( id:123 title: "An empty story" content: null expectedVersion: 2 ) { id author title content url ups downs version } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
La publicación actualizada en DynamoDB debería aparecer en el panel de resultados a la derecha del panel de consultas. Debería parecerse a lo que sigue:
{ "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 } } }
En esta solicitud, ha pedido a AWS AppSync y DynamoDB que actualicen únicamente el campo title
y content
. Los demás campos se quedan como estaban (salvo por el incremento del campo version
). Hemos establecido un nuevo valor en el atributo title
y hemos eliminado el atributo content
de la publicación. Los campos author
, url
, ups
y downs
no se han modificado.
Intente ejecutar la solicitud de mutación de nuevo, dejándola exactamente como está. Verá una respuesta parecida a la siguiente:
{ "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 solicitud falla porque la expresión de condición se evalúa como false:
-
La primera vez que ejecutamos la solicitud, el valor del campo
version
de la publicación en DynamoDB era2
, que coincidía con el argumentoexpectedVersion
. La solicitud se realizó correctamente, lo que significa que el campoversion
se incrementó en DynamoDB a3
. -
La segunda vez que ejecutamos la solicitud, el valor del campo
version
de la publicación en DynamoDB era3
, que no coincide con el argumentoexpectedVersion
.
Este método suele denominarse "bloqueo optimista".
Una de las características del solucionador de AWS AppSync DynamoDB es que devuelve el valor actual del objeto de publicación en DynamoDB. Puede encontrarlo en el campo data
, en la sección errors
de la respuesta de GraphQL. La aplicación puede utilizar esta información para decidir cómo debe proceder. En este caso, podemos ver que el campo version
del objeto en DynamoDB tiene el valor 3
, por lo que solo tendríamos que actualizar el argumento expectedVersion
a 3
para que la solicitud se ejecutase de nuevo.
Para obtener más información sobre cómo gestionar los casos en que no se cumpla la condición, consulte Expresiones de condición en la documentación de referencia de las plantillas de mapeo.
Cree mutaciones upvotePost y downvotePost (UpdateItem de DynamoDB)
El tipo Post
tiene campos ups
y downs
para registrar los votos a favor y en contra, pero hasta el momento la API no nos deja hacer nada con ellos. Vamos a agregar algunas mutaciones para votar a favor o en contra de las publicaciones.
-
Elija la pestaña Schema (Esquema).
-
En el panel Schema (Schema), modifique el tipo
Mutation
para agregar las nuevas mutacionesupvotePost
ydownvotePost
, de este modo: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! }
-
Seleccione Guardar.
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo upvotePost recién creado en el tipo Mutation y, a continuación, elija Attach (Asociar).
-
En el menú Acción, seleccione Actualizar tiempo de ejecución y, a continuación, elija Solucionador de unidades (solo VTL).
-
En Data source name (Nombre del tipo de datos), elija PostDynamoDBTable.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), pegue lo siguiente:
{ "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 } } } }
-
En Configure the response mapping template (Configurar la plantilla de mapeo de respuesta), pegue lo siguiente:
$utils.toJson($context.result)
-
Seleccione Guardar.
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo
downvotePost
recién creado en el tipo Mutation y, a continuación, elija Attach (Asociar). -
En Data source name (Nombre del tipo de datos), elija PostDynamoDBTable.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), pegue lo siguiente:
{ "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 } } } }
-
En Configure the response mapping template (Configurar la plantilla de mapeo de respuesta), pegue lo siguiente:
$utils.toJson($context.result)
-
Seleccione Guardar.
Llame a la API para votar a favor o en contra de una publicación
Ahora que se han configurado nuevos solucionadores, AWS AppSync ya sabe cómo convertir una mutación upvotePost
o downvote
entrante en una operación UpdateItem de DynamoDB. Ahora puede ejecutar mutaciones para votar a favor o en contra de la publicación que ha creado anteriormente.
-
Seleccione la pestaña Queries (Consultas).
-
En el panel Queries (Consultas), pegue la mutación siguiente. También tendrá que actualizar el argumento
id
con el valor que anotó anteriormente.mutation votePost { upvotePost(id:123) { id author title content url ups downs version } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
La publicación se actualiza en DynamoDB y debe aparecer en el panel de resultados a la derecha del panel de consultas. Debería parecerse a lo que sigue:
{ "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 } } }
-
Elija Execute query (Ejecutar consulta) algunas veces más. Debería ver cómo se incrementan en 1 los campos
ups
yversion
cada vez que ejecuta la consulta. -
Modifique la consulta para llamar a la mutación
downvotePost
de este modo:mutation votePost { downvotePost(id:123) { id author title content url ups downs version } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja). En esta ocasión, debería ver cómo se incrementan en 1 los campos
downs
yversion
cada vez que ejecuta la consulta.{ "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 } } }
Configuración de un solucionador deletePost (DeleteItem en DynamoDB)
La próxima mutación que desea configurar es la eliminación de una publicación. Para ello, utilizará la operación DeleteItem
de DynamoDB.
-
Elija la pestaña Schema (Esquema).
-
En el panel Schema (Esquema) modifique el tipo
Mutation
para agregar una nueva mutacióndeletePost
de este modo: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! }
Esta vez hemos declarado el campo
expectedVersion
como opcional, lo que se explica más adelante al añadir la plantilla de mapeo de solicitud. -
Seleccione Guardar.
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo delete recién creado en el tipo Mutation y, a continuación, elija Attach (Asociar).
-
En el menú Acción, seleccione Actualizar tiempo de ejecución y, a continuación, elija Solucionador de unidades (solo VTL).
-
En Data source name (Nombre del tipo de datos), elija PostDynamoDBTable.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), pegue lo siguiente:
{ "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 }
Nota: el argumento
expectedVersion
es opcional. Si el intermediario ha establecido un argumentoexpectedVersion
en la solicitud, entonces la plantilla añade una condición que solo permitirá que la solicitudDeleteItem
se atienda cuando el elemento se haya eliminado o cuando el atributoversion
de la publicación en DynamoDB coincida exactamente conexpectedVersion
. Si se omite, no se especificará ninguna expresión de condición para la solicitudDeleteItem
. Se realizará correctamente independientemente del valor deversion
o de si el elemento existe o no en DynamoDB. -
En Configure the response mapping template (Configurar la plantilla de mapeo de respuesta), pegue lo siguiente:
$utils.toJson($context.result)
Note: Aunque se trate de eliminar un elemento, puede devolver el elemento eliminado, siempre que no se haya eliminado previamente.
-
Seleccione Guardar.
Para obtener más información acerca del mapeo de la solicitud DeleteItem
, consulte la documentación de referencia de DeleteItem.
Llame a la API para eliminar una publicación
Ahora que ya está configurado el solucionador, AWS AppSync ya sabe cómo convertir una mutación delete
entrante en una operación DeleteItem
de DynamoDB. Ahora ya podemos ejecutar una mutación para eliminar datos de la tabla.
-
Seleccione la pestaña Queries (Consultas).
-
En el panel Queries (Consultas), pegue la mutación siguiente. También tendrá que actualizar el argumento
id
con el valor que anotó anteriormente.mutation deletePost { deletePost(id:123) { id author title content url ups downs version } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
La publicación se elimina de DynamoDB. Observe que AWS AppSync devuelve el valor del elemento que se ha eliminado de DynamoDB, que debe aparecer en el panel de resultados a la derecha del panel de consultas. Debería parecerse a lo que sigue:
{ "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 } } }
El valor solo se devuelve si esta llamada a deletePost
es realmente la que lo elimina de DynamoDB.
-
Elija Execute query (Ejecutar consulta) de nuevo.
-
La llamada se sigue ejecutando con éxito, pero no se devuelve ningún valor.
{ "data": { "deletePost": null } }
Ahora vamos a probar a eliminar una publicación, pero esta vez especificando expectedValue
. Primero tiene que crear una nueva, porque acaba de eliminar la publicación con la que ha estado trabajando hasta ahora.
-
En el panel Queries (Consultas), pegue la mutación siguiente:
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 } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
Los resultados de la publicación que acaba de crear deben aparecer en el panel de resultados a la derecha del panel de consultas. Anote el
id
del objeto recién creado, pues lo necesitaremos en breve. Debería parecerse a lo que sigue:{ "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 } } }
Ahora intentaremos eliminar esta publicación, pero especificaremos un valor erróneo en expectedVersion
:
-
En el panel Queries (Consultas), pegue la mutación siguiente. También tendrá que actualizar el argumento
id
con el valor que anotó anteriormente.mutation deletePost { deletePost( id:123 expectedVersion: 9999 ) { id author title content url ups downs version } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
{ "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 solicitud falla, porque la expresión de condición se evalúa como false: el valor de
version
de la publicación en DynamoDB no coincide con elexpectedValue
especificado en los argumentos. El valor actual del objeto se devuelve en el campodata
de la secciónerrors
de la respuesta de GraphQL. -
Vuelva a intentar la solicitud, pero corrija
expectedVersion
:mutation deletePost { deletePost( id:123 expectedVersion: 1 ) { id author title content url ups downs version } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
Esta vez la solicitud se realiza correctamente y se devuelve el valor eliminado en DynamoDB:
{ "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 } } }
-
Elija Execute query (Ejecutar consulta) de nuevo.
-
La llamada sigue realizándose, pero esta vez no se devuelve ningún valor, ya que la publicación ya se había eliminado en DynamoDB.
{ "data": { "deletePost": null } }
Configuración del solucionador allPost (Scan en DynamoDB)
Hasta ahora, la API solo es útil si conoce el id
de cada publicación que desea ver. Añada un nuevo solucionador que devuelva todas las publicaciones en la tabla.
-
Elija la pestaña Schema (Esquema).
-
En el panel Schema (Esquema) modifique el tipo
Query
para agregar una nueva consultaallPost
, de este modo:type Query { allPost(count: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }
-
Añada un nuevo tipo
PaginationPosts
:type PaginatedPosts { posts: [Post!]! nextToken: String }
-
Seleccione Guardar.
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo allPost recién creado en el tipo Query y, a continuación, elija Attach (Asociar).
-
En el menú Acción, seleccione Actualizar tiempo de ejecución y, a continuación, elija Solucionador de unidades (solo VTL).
-
En Data source name (Nombre del tipo de datos), elija PostDynamoDBTable.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), pegue lo siguiente:
{ "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 }
Este solucionador tiene dos argumentos opcionales:
count
, que especifica el número máximo de elementos que se devolverán en una sola llamada, ynextToken
, que se puede utilizar para recuperar el siguiente conjunto de resultados (más adelante mostrará de dónde procede el valor denextToken
). -
En Configure the response mapping template (Configurar la plantilla de mapeo de respuesta), pegue lo siguiente:
{ "posts": $utils.toJson($context.result.items) #if( ${context.result.nextToken} ) ,"nextToken": $util.toJson($context.result.nextToken) #end }
Nota: esta plantilla de mapeo de respuesta es diferente de todas las que hemos visto hasta ahora. El resultado de la consulta
allPost
es del tipoPaginatedPosts
, que contiene una lista de publicaciones y un token de paginación. La forma de este objeto es diferente a la que devuelve del solucionador para DynamoDB de AWS AppSync: la lista de publicaciones se llamaitems
en los resultados del solucionador para DynamoDB de AWS AppSync, pero se llamaposts
enPaginatedPosts
. -
Seleccione Guardar.
Si desea más información sobre el mapeo de solicitud Scan
, consulte la documentación de referencia de Scan.
Llame a la API para escanear todas las publicaciones
Ahora que ya está configurado el solucionador, AWS AppSync ya sabe cómo convertir una consulta allPost
entrante en una operación Scan
de DynamoDB. Ahora puede recorrer la tabla para obtener todas las publicaciones.
Sin embargo, antes de probarlo, debe rellenar la tabla datos, ya que hemos eliminado las publicaciones con las que hemos estado trabajado hasta ahora.
-
Seleccione la pestaña Queries (Consultas).
-
En el panel Queries (Consultas), pegue la mutación siguiente:
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 } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
Ahora recorreremos la tabla obteniendo cinco resultados cada vez.
-
En el panel Queries (Consultas), pegue la siguiente consulta:
query allPost { allPost(count: 5) { posts { id title } nextToken } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
Las cinco primeras publicaciones deben aparecer en el panel de resultados a la derecha del panel de consultas. Debería parecerse a lo que sigue:
{ "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=" } } }
Hemos obtenido cinco resultados y el valor nextToken
, que nos permite obtener el siguiente conjunto de resultados.
-
Actualice la consulta
allPost
para incluir el valor denextToken
del conjunto de resultados anterior:query allPost { allPost( count: 5 nextToken: "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnRlluNktJRWl6V0ZlR3hJOVJkaStrZUFBQUI1akNDQWVJR0NTcUdTSWIzRFFFSEJxQ0NBZE13Z2dIUEFnRUFNSUlCeUFZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5cW8yUGFSZThnalFpemRCTUNBUkNBZ2dHWk1JODhUNzhIOFVUZGtpdFM2ZFluSWRyVDg4c2lkN1RjZzB2d1k3VGJTTWpSQ2U3WjY3TkUvU2I1dWNETUdDMmdmMHErSGJSL0pteGRzYzVEYnE1K3BmWEtBdU5jSENJdWNIUkJ0UHBPWVdWdCtsS2U5L1pNcWdocXhrem1RaXI1YnIvQkt6dU5hZmJCdE93NmtoM2Jna1BKM0RjWWhpMFBGbmhMVGg4TUVGSjBCcXg3RTlHR1V5N0tUS0JLZlV3RjFQZ0JRREdrNzFYQnFMK2R1S2IrVGtZZzVYMjFrc3NyQmFVTmNXZmhTeXE0ZUJHSWhqZWQ5c3VKWjBSSTc2ZnVQdlZkR3FLNENjQmxHYXhpekZnK2pKK1FneEU1SXduRTNYYU5TR0I4QUpmamR2bU1wbUk1SEdvWjlMUUswclczbG14RDRtMlBsaTNLaEVlcm9pem5zcmdINFpvcXIrN2ltRDN3QkJNd3BLbGQzNjV5Nnc4ZnMrK2FnbTFVOUlKOFFrOGd2bEgySHFROHZrZXBrMWlLdWRIQ25LaS9USnBlMk9JeEVPazVnRFlzRTRUU09HUlVJTkxYY2MvdW1WVEpBMUthV2hWTlAvdjNlSnlZQUszbWV6N2h5WHVXZ1BkTVBNWERQdTdjVnVRa3EwK3NhbGZOd2wvSUx4bHNyNDVwTEhuVFpyRWZvVlV1bXZ5S2VKY1RUU1lET05hM1NwWEd2UT09In0=" ) { posts { id author } nextToken } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
Las cuatro publicaciones restantes deben aparecer en el panel de resultados a la derecha del panel de consultas. No hay ningún
nextToken
en este conjunto, porque ya ha recorrido las nueve publicaciones y no quedan más. Debería parecerse a lo que sigue:{ "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 } } }
Configuración del solucionador allPostsByAuthor (Query de DynamoDB)
Además de escanear DynamoDB para obtener todas las publicaciones, también puede consultar DynamoDB para obtener las publicaciones creadas por un autor determinado. La tabla de DynamoDB que creó anteriormente ya tiene un GlobalSecondaryIndex
llamado author-index
que puede utilizar con una operación Query
de DynamoDB para recuperar todas las publicaciones creadas por un autor determinado.
-
Elija la pestaña Schema (Esquema).
-
En el panel Schema (Esquema) modifique el tipo
Query
para agregar una nueva consultaallPostsByAuthor
, de este modo:type Query { allPostsByAuthor(author: String!, count: Int, nextToken: String): PaginatedPosts! allPost(count: Int, nextToken: String): PaginatedPosts! getPost(id: ID): Post }
Nota: aquí vuelve a usarse el tipo
PaginatedPosts
que empleamos en la consultaallPost
. -
Seleccione Guardar.
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo allPostsByAuthor recién creado en el tipo Query y, a continuación, elija Attach (Asociar).
-
En el menú Acción, seleccione Actualizar tiempo de ejecución y, a continuación, elija Solucionador de unidades (solo VTL).
-
En Data source name (Nombre del tipo de datos), elija PostDynamoDBTable.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), pegue lo siguiente:
{ "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 }
Al igual que el solucionador
allPost
, este solucionador tiene dos argumentos opcionales:count
, que especifica el número máximo de elementos que se devolverá en una sola llamada, ynextToken
, que se puede utilizar para recuperar el siguiente conjunto de resultados (el valor paranextToken
se puede obtener en una llamada anterior). -
En Configure the response mapping template (Configurar la plantilla de mapeo de respuesta), pegue lo siguiente:
{ "posts": $utils.toJson($context.result.items) #if( ${context.result.nextToken} ) ,"nextToken": $util.toJson($context.result.nextToken) #end }
Nota: esta es la misma plantilla de mapeo de respuesta que usamos en el solucionador
allPost
. -
Seleccione Guardar.
Si desea más información sobre el mapeo de solicitud Query
, consulte la documentación de referencia de Query.
Llame a la API para consultar todas las publicaciones de un autor
Ahora que se ha configurado el solucionador, AWS AppSync ya sabe cómo convertir una mutación allPostsByAuthor
entrante en una operación Query
de DynamoDB referida al índice author-index
. Ahora puede consultar la tabla para recuperar todas las publicaciones de un autor determinado.
Sin embargo, antes de hacerlo, debemos rellenar la tabla con algunas publicaciones más, ya que por el momento todas son del mismo autor.
-
Seleccione la pestaña Queries (Consultas).
-
En el panel Queries (Consultas), pegue la mutación siguiente:
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 } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
Ahora consultaremos la tabla para que devuelva todas las publicaciones creadas por Nadia
.
-
En el panel Queries (Consultas), pegue la siguiente consulta:
query allPostsByAuthor { allPostsByAuthor(author: "Nadia") { posts { id title } nextToken } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
Todas las publicaciones creadas por
Nadia
deben aparecer en el panel de resultados a la derecha del panel de consultas. Debería parecerse a lo que sigue:{ "data": { "allPostsByAuthor": { "posts": [ { "id": "10", "title": "The cutest dog in the world" }, { "id": "11", "title": "Did you know...?" } ], "nextToken": null } } }
La paginación funciona con Query
de igual modo que con Scan
. Por ejemplo, vamos a buscar todas las publicaciones de AUTHORNAME
y obtener cinco cada vez.
-
En el panel Queries (Consultas), pegue la siguiente consulta:
query allPostsByAuthor { allPostsByAuthor( author: "AUTHORNAME" count: 5 ) { posts { id title } nextToken } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
Todas las publicaciones creadas por
AUTHORNAME
deben aparecer en el panel de resultados a la derecha del panel de consultas. Debería parecerse a lo que sigue:{ "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==" } } }
-
Actualice el argumento
nextToken
con el valor devuelto en la consulta anterior, de este modo:query allPostsByAuthor { allPostsByAuthor( author: "AUTHORNAME" count: 5 nextToken: "eyJ2ZXJzaW9uIjoxLCJ0b2tlbiI6IkFRSUNBSGo4eHR0RG0xWXhUa1F0cEhXMEp1R3B0M1B3eThOSmRvcG9ad2RHYjI3Z0lnSExqRnVhVUR3ZUhEZ2QzNGJ2QlFuY0FBQUNqekNDQW9zR0NTcUdTSWIzRFFFSEJxQ0NBbnd3Z2dKNEFnRUFNSUlDY1FZSktvWklodmNOQVFjQk1CNEdDV0NHU0FGbEF3UUJMakFSQkF5Qkg4Yk1obW9LVEFTZHM3SUNBUkNBZ2dKQ3dISzZKNlJuN3pyYUVKY1pWNWxhSkNtZW1KZ0F5N1dhZkc2UEdTNHpNQzJycTkwZHFJTFV6Z25wck9Gd3pMS3VOQ2JvUXc3VDI5eCtnVExIbGg4S3BqbzB1YjZHQ3FwcDhvNDVmMG9JbDlmdS9JdjNXcFNNSXFKTXZ1MEVGVWs1VzJQaW5jZGlUaVRtZFdYWlU1bkV2NkgyRFBRQWZYYlNnSmlHSHFLbmJZTUZZM0FTdmRIL0hQaVZBb1RCMk1YZkg0eGJOVTdEbjZtRFNhb2QwbzdHZHJEWDNtODQ1UXBQUVNyUFhHemY0WDkyajhIdlBCSWE4Smcrb0RxbHozUVQ5N2FXUXdYWWU2S0h4emI1ejRITXdEdXEyRDRkYzhoMi9CbW10MzRMelVGUVIyaExSZGRaZ0xkdzF5cHJZdFZwY3dEc1d4UURBTzdOcjV2ZEp4VVR2TVhmODBRSnp1REhXREpTVlJLdDJwWmlpaXhXeGRwRmNod1BzQ3d2aVBqMGwrcWFFWU1jMXNQbENkVkFGem43VXJrSThWbS8wWHlwR2xZb3BSL2FkV0xVekgrbGMrYno1ZEM2SnVLVXdtY1EyRXlZeDZiS0Izbi9YdUViWGdFeU5PMWZTdE1rRlhyWmpvMVpzdlYyUFRjMzMrdEs0ZDhkNkZrdjh5VVR6WHhJRkxIaVNsOUx6VVdtT3BCaWhrTFBCT09jcXkyOHh1UmkzOEM3UFRqMmN6c3RkOUo1VUY0azBJdUdEbVZzM2xjdWg1SEJjYThIeXM2aEpvOG1HbFpMNWN6R2s5bi8vRE1EbDY3RlJraG5QNFNhSDBpZGI5VFEvMERLeFRBTUdhcWpPaEl5ekVqd2ZDQVJleFdlbldyOGlPVkhScDhGM25WZVdvbFRGK002N0xpdi9XNGJXdDk0VEg3b0laUU5lYmZYKzVOKy9Td25Hb1dyMTlWK0pEb2lIRVFLZ1cwMWVuYjZKUXo5Slh2Tm95ZzF3RnJPVmxGc2xwNlRHa1BlN2Rnd2IrWT0ifQ==" ) { posts { id title } nextToken } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
Las demás publicaciones creadas por
AUTHORNAME
deben aparecer en el panel de resultados a la derecha del panel de consultas. Debería parecerse a lo que sigue:{ "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 } } }
Uso de conjuntos
Hasta ahora, el tipo Post
era un objeto clave/valor plano. El solucionador AppSyncDynamoDB de AWS también permite modelar objetos complejos, como conjuntos, listas y mapas.
Vamos a actualizar el tipo Post
para incluir etiquetas. Una publicación puede tener cero o más etiquetas, que se almacenan en DynamoDB como un conjunto de cadenas. También configuraremos algunas mutaciones para añadir y eliminar etiquetas, y una nueva consulta para buscar las publicaciones con una etiqueta concreta.
-
Elija la pestaña Schema (Esquema).
-
En el panel Schema (Esquema) modifique el tipo
Post
para agregar un nuevo campotags
, de este modo:type Post { id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! tags: [String!] }
-
En el panel Schema (Esquema) modifique el tipo
Query
para agregar una nueva consultaallPostsByTag
, de este modo: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 }
-
En el panel Schema (Schema), modifique el tipo
Mutation
para agregar las nuevas mutacionesaddTag
yremoveTag
, de este modo: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! }
-
Seleccione Guardar.
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo allPostsByTag recién creado en el tipo Query y, a continuación, elija Attach (Asociar).
-
En Data source name (Nombre del tipo de datos), elija PostDynamoDBTable.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), pegue lo siguiente:
{ "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 }
-
En Configure the response mapping template (Configurar la plantilla de mapeo de respuesta), pegue lo siguiente:
{ "posts": $utils.toJson($context.result.items) #if( ${context.result.nextToken} ) ,"nextToken": $util.toJson($context.result.nextToken) #end }
-
Seleccione Guardar.
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo addTag recién creado en el tipo Mutation y, a continuación, elija Attach (Asociar).
-
En Data source name (Nombre del tipo de datos), elija PostDynamoDBTable.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), pegue lo siguiente:
{ "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 } } } }
-
En Configure the response mapping template (Configurar la plantilla de mapeo de respuesta), pegue lo siguiente:
$utils.toJson($context.result)
-
Seleccione Guardar.
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo removeTag recién creado en el tipo Mutation y, a continuación, elija Attach (Asociar).
-
En Data source name (Nombre del tipo de datos), elija PostDynamoDBTable.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), pegue lo siguiente:
{ "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 } } } }
-
En Configure the response mapping template (Configurar la plantilla de mapeo de respuesta), pegue lo siguiente:
$utils.toJson($context.result)
-
Seleccione Guardar.
Llame a la API para trabajar con etiquetas
Ahora que ha configurado los solucionadores, AWS AppSync sabe cómo convertir solicitudes addTag
, removeTag
y allPostsByTag
entrantes en operaciones Scan
y UpdateItem
de DynamoDB.
Para probarlo, vamos a seleccionar una de las publicaciones que ha creado anteriormente. Por ejemplo, tomemos una publicación creada por Nadia
.
-
Seleccione la pestaña Queries (Consultas).
-
En el panel Queries (Consultas), pegue la siguiente consulta:
query allPostsByAuthor { allPostsByAuthor( author: "Nadia" ) { posts { id title } nextToken } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
Todas las publicaciones creadas por Nadia deben aparecer en el panel de resultados a la derecha del panel de consultas. Debería parecerse a lo que sigue:
{ "data": { "allPostsByAuthor": { "posts": [ { "id": "10", "title": "The cutest dog in the world" }, { "id": "11", "title": "Did you known...?" } ], "nextToken": null } } }
-
Usemos el que tiene el título
"The cutest dog in the world"
. Anote suid
, ya que vamos a utilizarlo más adelante.
Ahora probemos a añadirle la etiqueta dog
.
-
En el panel Queries (Consultas), pegue la mutación siguiente. También tendrá que actualizar el argumento
id
con el valor que anotó anteriormente.mutation addTag { addTag(id:10 tag: "dog") { id title tags } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
La publicación se actualiza con la nueva etiqueta.
{ "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog" ] } } }
Puede agregar más etiquetas, de este modo:
-
Actualice la mutación para cambiar el argumento
tag
apuppy
.mutation addTag { addTag(id:10 tag: "puppy") { id title tags } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
La publicación se actualiza con la nueva etiqueta.
{ "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog", "puppy" ] } } }
También puede eliminar etiquetas:
-
En el panel Queries (Consultas), pegue la mutación siguiente. También tendrá que actualizar el argumento
id
con el valor que anotó anteriormente.mutation removeTag { removeTag(id:10 tag: "puppy") { id title tags } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
La publicación se actualiza y la etiqueta
puppy
se elimina.{ "data": { "addTag": { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog" ] } } }
También puede buscar todas las publicaciones que tengan una etiqueta:
-
En el panel Queries (Consultas), pegue la siguiente consulta:
query allPostsByTag { allPostsByTag(tag: "dog") { posts { id title tags } nextToken } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
Se devolverán todas las publicaciones que tenga la etiqueta
dog
, de este modo:{ "data": { "allPostsByTag": { "posts": [ { "id": "10", "title": "The cutest dog in the world", "tags": [ "dog", "puppy" ] } ], "nextToken": null } } }
Uso de listas y mapas
Además de usar conjuntos de DynamoDB, también puede usar las listas y mapas de DynamoDB para modelar datos complejos con un único objeto.
Vamos a añadir la capacidad de agregar comentarios a las publicaciones. Esto se modelará como una lista de objetos de mapa para el objeto Post
en DynamoDB.
Nota: en una aplicación real, los comentarios se incluirían en su propia tabla. Para este tutorial, nos limitaremos a añadirlos a la tabla Post
.
-
Elija la pestaña Schema (Esquema).
-
En el panel Schema (Esquema), agregue un nuevo tipo
Comment
de este modo:type Comment { author: String! comment: String! }
-
En el panel Schema (Esquema) modifique el tipo
Post
para agregar un nuevo campocomments
, de este modo:type Post { id: ID! author: String title: String content: String url: String ups: Int! downs: Int! version: Int! tags: [String!] comments: [Comment!] }
-
En el panel Schema (Esquema) modifique el tipo
Mutation
para agregar una nueva mutaciónaddComment
de este modo: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! }
-
Seleccione Guardar.
-
En el panel Data types (Tipos de datos) de la derecha, busque el campo addComment recién creado en el tipo Mutation y, a continuación, elija Attach (Asociar).
-
En Data source name (Nombre del tipo de datos), elija PostDynamoDBTable.
-
En Configure the request mapping template (Configurar la plantilla de mapeo de solicitud), pegue lo siguiente:
{ "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) } } }
Esta expresión de actualización agregará una lista con nuestro nuevo comentario a la lista
comments
existente. Si la lista no existe todavía, se creará. -
En Configure the response mapping template (Configurar la plantilla de mapeo de respuesta), pegue lo siguiente:
$utils.toJson($context.result)
-
Seleccione Guardar.
Llame a la API para añadir un comentario
Ahora que ha configurado los solucionadores, AWS AppSync sabe cómo convertir solicitudes addComment
entrantes en operaciones UpdateItem
de DynamoDB.
Vamos a probarlo añadiendo un comentario a la misma publicación a la que añadimos las etiquetas.
-
Seleccione la pestaña Queries (Consultas).
-
En el panel Queries (Consultas), pegue la siguiente consulta:
mutation addComment { addComment( id:10 author: "Steve" comment: "Such a cute dog." ) { id comments { author comment } } }
-
Elija Execute query (Ejecutar consulta) (el botón de reproducción naranja).
-
Todas las publicaciones creadas por Nadia deben aparecer en el panel de resultados a la derecha del panel de consultas. Debería parecerse a lo que sigue:
{ "data": { "addComment": { "id": "10", "comments": [ { "author": "Steve", "comment": "Such a cute dog." } ] } } }
Si ejecuta la solicitud varias veces, se agregarán varios comentarios a la lista.
Conclusión
En este tutorial ha creado una API que nos permite manipular objetos Post en DynamoDB mediante AWS AppSync y GraphQL. Para obtener más información, consulte la Referencia de plantillas de mapeo de solucionador para Elasticsearch.
Para limpiar, puede eliminar la API de GraphQL de AppSync de la consola.
Para eliminar la tabla de DynamoDB y el rol de IAM que ha creado para este tutorial, puede ejecutar lo siguiente para eliminar la pila AWSAppSyncTutorialForAmazonDynamoDB
o ir a la consola de AWS CloudFormation y eliminar la pila:
aws cloudformation delete-stack \ --stack-name AWSAppSyncTutorialForAmazonDynamoDB