

Las traducciones son generadas a través de traducción automática. En caso de conflicto entre la traducción y la version original de inglés, prevalecerá la version en inglés.

# Creación de una aplicación posterior sencilla con resolutores de DynamoDB JavaScript
<a name="tutorial-dynamodb-resolvers-js"></a>

En este tutorial, importará sus tablas de Amazon DynamoDB y las conectará AWS AppSync para crear una API de GraphQL totalmente funcional mediante solucionadores de canalización que puede JavaScript utilizar en su propia aplicación.

Utilizará la AWS AppSync consola para aprovisionar sus recursos de Amazon DynamoDB, crear sus resolutores y conectarlos a sus fuentes de datos. También podrá leer y escribir en la base de datos de Amazon DynamoDB a través de instrucciones de GraphQL y suscribirse a datos en tiempo real.

Existen pasos específicos que deben completarse para que las instrucciones de GraphQL se traduzcan a operaciones de Amazon DynamoDB y para que las respuestas se vuelvan a traducir 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.

## Creación de la API de GraphQL
<a name="create-graphql-api"></a>

**Para crear una API de GraphQL en AWS AppSync**

1. Abre la AppSync consola y selecciona **Crear API**.

1. Seleccione **Diseñar desde cero** y elija **Siguiente**.

1. Llame a su API `PostTutorialAPI` y, a continuación, seleccione **Siguiente**. Vaya a la página de revisión dejando el resto de las opciones con sus valores predeterminados y seleccione `Create`.

La AWS AppSync consola crea una nueva API de GraphQL para usted. De forma predeterminada, utiliza el modo de autenticación con 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
<a name="define-post-api"></a>

Ahora que tiene una API de GraphQL, puede configurar un esquema básico que permita la creación, recuperación y eliminación básica de datos de publicaciones.

**Para añadir datos a su esquema**

1. En su API, seleccione la pestaña **Esquema**.

1. Crearemos un esquema que defina un tipo `Post` y una operación `addPost` para añadir y obtener objetos `Post`. 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!
   }
   ```

1. Elija **Save Schema (Guardar esquema)**.

## Configuración de la tabla de Amazon DynamoDB
<a name="configure-dynamodb"></a>

La AWS AppSync consola puede ayudarle a aprovisionar los AWS recursos necesarios para almacenar sus propios recursos en una tabla de Amazon DynamoDB. En este paso, creará una tabla de Amazon DynamoDB para almacenar sus publicaciones. También configurará un [índice secundario](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/SecondaryIndexes.html) que utilizaremos más adelante.

**Para crear una tabla de Amazon DynamoDB**

1. En la página **Esquema**, seleccione **Crear recursos**.

1. Elija **Usar tipo existente** y, a continuación, elija el tipo `Post`.

1. En la sección **Índices secundarios**, elija **Añadir índice**.

1. Llame al índice `author-index`.

1. Establezca el `Primary key` en `author` y la clave `Sort` en `None`.

1. Deshabilite **Generación automática de GraphQL**. En este ejemplo, vamos a crear el solucionador nosotros mismos.

1. Seleccione **Crear**.

Ahora tiene un nuevo origen de datos llamado `PostTable`, que puede ver en **Orígenes de datos** en la pestaña lateral. Este origen de datos se utiliza para vincular las consultas y mutaciones a la tabla de Amazon DynamoDB. 

## Configuración de un solucionador de AddPost (Amazon DynamoDB) PutItem
<a name="configure-addpost"></a>

Ahora que AWS AppSync conoce la tabla Amazon DynamoDB, puede vincularla a consultas y mutaciones individuales definiendo resolutores. La primera resolución que cree es la resolución de `addPost` canalización que utiliza JavaScript, que le permite crear una publicación en la tabla de Amazon DynamoDB. Un solucionador de canalización tiene los siguientes componentes: 
+ La ubicación en el esquema de GraphQL donde se asocia el solucionador. En este caso configuramos en el campo `createPost` un solucionador de tipo `Mutation`. El solucionador se invocará cuando el intermediario llame a la mutación `{ addPost(...){...} }`. 
+ El origen de datos que se va a utilizar para el solucionador. En este caso, queremos utilizar el origen de datos de DynamoDB definido anteriormente para poder añadir entradas en la tabla `post-table-for-tutorial` de DynamoDB.
+ El controlador de solicitudes. El controlador de solicitudes es una función que gestiona la solicitud entrante de la persona que llama y la traduce en instrucciones AWS AppSync para ejecutarlas en DynamoDB.
+ El controlador de respuestas. El cometido del controlador de respuestas es gestionar 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**

1. En su API, seleccione la pestaña **Esquema**.

1. En el panel **Solucionadores**, busque el campo `addPost` debajo del tipo `Mutation` y, a continuación, seleccione **Asociar**.

1. Elija el origen de datos y, a continuación, seleccione **Crear**.

1. En su editor de código, reemplace el código por este fragmento:

   ```
   import { util } from '@aws-appsync/utils'
   import * as ddb from '@aws-appsync/utils/dynamodb'
   
   export function request(ctx) {
   	const item = { ...ctx.arguments, ups: 1, downs: 0, version: 1 }
   	const key = { id: ctx.args.id ?? util.autoId() }
   	return ddb.put({ key, item })
   }
   
   export function response(ctx) {
   	return ctx.result
   }
   ```

1. Seleccione **Save**.

**nota**  
En este código, se emplean las utilidades del módulo de DynamoDB que permiten crear fácilmente solicitudes de DynamoDB.

AWS AppSync viene con una utilidad para la generación automática de ID llamada`util.autoId()`, que se utiliza para generar una ID para su nueva publicación. Si no especifica un identificador, la utilidad lo generará automáticamente.

```
const key = { id: ctx.args.id ?? util.autoId() }
```

Para obtener más información sobre las utilidades disponibles JavaScript, consulte [las características JavaScript de tiempo de ejecución para resoluciones y funciones](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-util-reference-js.html). 

### Llame a la API para añadir una publicación
<a name="call-api-addpost"></a>

Ahora que se ha configurado el solucionador, AWS AppSync puede convertir una `addPost` mutación entrante en una operación de Amazon `PutItem` DynamoDB. Ahora puede ejecutar una mutación para incluir datos en la tabla.

**Para ejecutar la operación**

1. En su API, seleccione la pestaña **Consultas**.

1. En el panel **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
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `addPost`. Los resultados de la publicación que acaba de crear deben aparecer en el panel **Resultados** a la derecha del panel **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
       }
     }
   }
   ```

La siguiente explicación muestra lo que ocurrió:

1. AWS AppSync recibió una solicitud de `addPost` mutación.

1. AWS AppSync ejecuta el gestor de solicitudes del solucionador. La función `ddb.put` crea una solicitud `PutItem` similar a la siguiente:

   ```
   {
     operation: 'PutItem',
     key: { id: { S: '123' } },
     attributeValues: {
       downs: { N: 0 },
       author: { S: 'AUTHORNAME' },
       ups: { N: 1 },
       title: { S: 'Our first post!' },
       version: { N: 1 },
       content: { S: 'This is our first post.' },
       url: { S: 'https://aws.amazon.com/appsync/' }
     }
   }
   ```

1. AWS AppSync utiliza este valor para generar y ejecutar una solicitud de Amazon `PutItem` DynamoDB.

1. AWS AppSync tomó los resultados de la `PutItem` solicitud y los volvió a convertir a tipos 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
   }
   ```

1. El controlador de respuestas devuelve el resultado inmediatamente (`return ctx.result`).

1. El resultado final es visible en la respuesta de GraphQL.

## Configuración del solucionador GetPost (Amazon DynamoDB) GetItem
<a name="configure-getpost"></a>

Ahora que puede añadir datos a la tabla de Amazon DynamoDB, tiene que configurar la consulta `getPost` para poder recuperar los datos de la tabla. Para ello, tiene que configurar otro solucionador.

**Para añadir su solucionador**

1. En su API, seleccione la pestaña **Esquema**.

1. En el panel **Solucionadores** a la derecha, busque el campo `getPost` en el tipo `Query` y, a continuación, seleccione **Asociar**.

1. Elija el origen de datos y, a continuación, seleccione **Crear**.

1. En el editor de código, sustituya el código por este fragmento:

   ```
   import * as ddb from '@aws-appsync/utils/dynamodb'
   	
   export function request(ctx) {
   	return ddb.get({ key: { id: ctx.args.id } })
   }
   
   export const response = (ctx) => ctx.result
   ```

1. Guarde el solucionador.

**nota**  
En este solucionador, utilizamos una expresión de función de flecha para el controlador de respuestas.

### Llame a la API para obtener una publicación
<a name="call-api-getpost"></a>

Ahora que el solucionador está configurado, AWS AppSync sabe cómo convertir una `getPost` consulta entrante en una operación de Amazon `GetItem` DynamoDB. Ahora puede ejecutar una consulta para recuperar la publicación que ha creado anteriormente.

**Para ejecutar su consulta**

1. En su API, seleccione la pestaña **Consultas**. 

1. En el panel **Consultas**, añada el siguiente código y use el identificador que copió después de crear su publicación:

   ```
   query getPost {
     getPost(id: "123") {
       id
       author
       title
       content
       url
       ups
       downs
       version
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `getPost`. Los resultados de la publicación que acaba de crear deben aparecer en el panel **Resultados** a la derecha del panel **Consultas**.

1. Los resultados obtenidos de Amazon DynamoDB deben aparecer en el panel **Resultados** a la derecha del panel **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
       }
     }
   }
   ```

Como alternativa, vamos a tomar el siguiente ejemplo:

```
query getPost {
  getPost(id: "123") {
    id
    author
    title
  }
}
```

Si la consulta `getPost` solo necesita el `id`, `author` y `title`, puede cambiar la función de solicitud 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 función de solicitud puede tener un aspecto similar al siguiente fragmento:

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	return ddb.get({
		key: { id: ctx.args.id },
		projection: ['author', 'id', 'title'],
	})
}

export const response = (ctx) => ctx.result
```

También puede usar un [selectionSetList](https://docs.aws.amazon.com/appsync/latest/devguide/resolver-context-reference-js.html#aws-appsync-resolver-context-reference-info-js)ancho `getPost` para representar lo siguiente: `expression`

```
import * as ddb from '@aws-appsync/utils/dynamodb'

export function request(ctx) {
	const projection = ctx.info.selectionSetList.map((field) => field.replace('/', '.'))
	return ddb.get({ key: { id: ctx.args.id }, projection })
}

export const response = (ctx) => ctx.result
```

## Crear una mutación de UpdatePost (Amazon DynamoDB) UpdateItem
<a name="configure-updatepost"></a>

De momento, ya sabe crear y recuperar objetos `Post` en Amazon DynamoDB. A continuación, va a configurar una nueva mutación para actualizar objetos. En comparación con la mutación `addPost`, que requiere que se especifiquen todos los campos, esta mutación le permite especificar solo los campos que desea cambiar. También introdujo un nuevo argumento `expectedVersion` que permite especificar la versión que se quiere modificar. Va a configurar una condición que garantice que está modificando la versión más reciente del objeto. Para ello, utilizará la operación `UpdateItem` de Amazon DynamoDB.

**Para actualizar su solucionador**

1. En su API, seleccione la pestaña **Esquema**.

1. En el panel **Schema (Esquema)** modifique el tipo `Mutation` para agregar una nueva mutación `updatePost` de este modo:

   ```
   type Mutation {
       updatePost(
           id: ID!,
           author: String,
           title: String,
           content: String,
           url: String,
           expectedVersion: Int!
       ): Post
       
       addPost(
           id: ID
           author: String!
           title: String!
           content: String!
           url: String!
       ): Post!
   }
   ```

1. Elija **Save Schema (Guardar esquema)**.

1. En el panel **Solucionadores** de la derecha, busque el campo `updatePost` recién creado en el tipo `Mutation` y, a continuación, seleccione **Asociar**. Cree su nuevo solucionador con el siguiente fragmento:

   ```
   import { util } from '@aws-appsync/utils';
   import * as ddb from '@aws-appsync/utils/dynamodb';
   
   export function request(ctx) {
     const { id, expectedVersion, ...rest } = ctx.args;
     const values = Object.entries(rest).reduce((obj, [key, value]) => {
       obj[key] = value ?? ddb.operations.remove();
       return obj;
     }, {});
   
     return ddb.update({
       key: { id },
       condition: { version: { eq: expectedVersion } },
       update: { ...values, version: ddb.operations.increment(1) },
     });
   }
   
   export function response(ctx) {
     const { error, result } = ctx;
     if (error) {
       util.appendError(error.message, error.type);
     }
     return result;
   ```

1. Guarde los cambios que haya realizado.

Este solucionador utiliza `ddb.update` para crear una solicitud `UpdateItem` de Amazon DynamoDB. En lugar de escribir el elemento completo, solo pide a Amazon DynamoDB que actualice determinados atributos. Esto se consigue mediante expresiones de actualización de Amazon DynamoDB.

La función `ddb.update` toma como argumentos una clave y un objeto de actualización. A continuación, se comprueban los valores de los argumentos entrantes. Cuando un valor esté establecido en `null`, utilice la operación `remove` de DynamoDB para indicar que el valor debe eliminarse del elemento de DynamoDB.

También hay una nueva sección `condition`. Una expresión de condición le permite indicar AWS AppSync a Amazon DynamoDB si la solicitud debe realizarse correctamente o no en función del estado del objeto que ya se encuentra en Amazon DynamoDB antes de realizar la operación. En este caso, solo quiere que la solicitud `UpdateItem` se realice si el campo `version` del elemento que hay en Amazon DynamoDB coincide exactamente con el argumento `expectedVersion`. Cuando se actualice el elemento, queremos incrementar el valor de `version`. Esto es fácil de hacer con la función de operación `increment`.

Si desea más información sobre las expresiones de condición, consulte la documentación de [expresiones de condición](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-condition-expressions).

Para obtener más información sobre la `UpdateItem` solicitud, consulte la [UpdateItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-updateitem)documentación y la documentación del [módulo DynamoDB](https://docs.aws.amazon.com/appsync/latest/devguide/built-in-modules-js.html). 

Para obtener más información sobre cómo escribir expresiones de actualización, consulte la documentación de [ UpdateExpressionsDynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Expressions.UpdateExpressions.html).

### Llame a la API para actualizar una publicación
<a name="call-api-updatepost"></a>

Vamos a intentar actualizar el objeto `Post` con el nuevo solucionador.

**Para actualizar el objeto**

1. En su API, seleccione la pestaña **Consultas**.

1. En el panel **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: 1
     ) {
       id
       author
       title
       content
       url
       ups
       downs
       version
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `updatePost`.

1. La publicación actualizada en Amazon DynamoDB debería aparecer en el panel **Resultados** a la derecha del panel **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": 2
       }
     }
   }
   ```

En esta solicitud, ha pedido a Amazon DynamoDB que actualice `title` únicamente los campos AWS AppSync y. `content` Todos los demás campos se han quedado 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": null,
      "errorType": "DynamoDB:ConditionalCheckFailedException",
      "errorInfo": null,
      "locations": [
        {
          "line": 2,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "The conditional request failed (Service: DynamoDb, Status Code: 400, Request ID: 1RR3QN5F35CS8IV5VR4OQO9NNBVV4KQNSO5AEMVJF66Q9ASUAAJG)"
    }
  ]
}
```

La solicitud falla porque la expresión de condición se evalúa como `false`: 

1. La primera vez que ejecutamos la solicitud, el valor del campo `version` de la publicación en Amazon DynamoDB era `1`, que coincidía con el argumento `expectedVersion`. La solicitud se realizó correctamente, lo que significa que el campo `version` se incrementó en Amazon DynamoDB a `2`.

1. La segunda vez que ejecutamos la solicitud, el valor del campo `version` de la publicación en Amazon DynamoDB era `2`, que no coincide con el argumento `expectedVersion`.

Este método suele denominarse *"bloqueo optimista"*.

## Crear mutaciones de votos (Amazon DynamoDB UpdateItem)
<a name="configure-vote-mutations"></a>

El tipo `Post` contiene los campos `ups` y `downs` para permitir el registro de votos a favor y en contra. Sin embargo, en este momento la API no nos permite hacer nada con ellos. Vamos a añadir una mutación para votar a favor o en contra de las publicaciones.

**Para añadir su mutación**

1. En su API, seleccione la pestaña **Esquema**.

1. En el panel **Esquema**, modifique el tipo `Mutation` y añada la enumeración `DIRECTION` para añadir nuevas mutaciones de votos:

   ```
   type Mutation {
       vote(id: ID!, direction: DIRECTION!): Post
       updatePost(
           id: ID!,
           author: String,
           title: String,
           content: String,
           url: String,
           expectedVersion: Int!
       ): Post
       addPost(
           id: ID,
           author: String!,
           title: String!,
           content: String!,
           url: String!
       ): Post!
   }
   
   enum DIRECTION {
     UP
     DOWN
   }
   ```

1. Elija **Save Schema (Guardar esquema)**.

1. En el panel **Solucionadores** de la derecha, busque el campo `vote` recién creado en el tipo `Mutation` y, a continuación, seleccione **Asociar**. Para crear un nuevo solucionador, cree y reemplace el código por el siguiente fragmento:

   ```
   import * as ddb from '@aws-appsync/utils/dynamodb';
   
   export function request(ctx) {
     const field = ctx.args.direction === 'UP' ? 'ups' : 'downs';
     return ddb.update({
       key: { id: ctx.args.id },
       update: {
         [field]: ddb.operations.increment(1),
         version: ddb.operations.increment(1),
       },
     });
   }
   
   export const response = (ctx) => ctx.result;
   ```

1. Guarde los cambios que haya realizado.

### Llame a la API para votar a favor o en contra de una publicación
<a name="call-api-vote"></a>

Ahora que se han configurado los nuevos resolutores, AWS AppSync sabe cómo convertir una operación entrante `upvotePost` o una `downvote` mutación en una operación de Amazon DynamoDB`UpdateItem`. Ahora puede ejecutar mutaciones para votar a favor o en contra de la publicación que ha creado anteriormente.

**Para ejecutar su mutación**

1. En su API, seleccione la pestaña **Consultas**.

1. En el panel **Consultas**, pegue la mutación siguiente. También tendrá que actualizar el argumento `id` con el valor que anotó anteriormente:

   ```
   mutation votePost {
     vote(id:123, direction: UP) {
       id
       author
       title
       content
       url
       ups
       downs
       version
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `votePost`.

1. La publicación actualizada en Amazon DynamoDB debería aparecer en el panel **Resultados** a la derecha del panel **Consultas**. Debería parecerse a lo que sigue:

   ```
   {
     "data": {
       "vote": {
         "id": "123",
         "author": "A new author",
         "title": "An empty story",
         "content": null,
         "url": "https://aws.amazon.com/appsync/",
         "ups": 6,
         "downs": 0,
         "version": 4
       }
     }
   }
   ```

1. Seleccione **Ejecutar** unas cuantas veces más. Debería ver cómo se incrementan en `1` los campos `ups` y `version` cada vez que ejecuta la consulta.

1. Cambie la consulta para llamarla con una `DIRECTION` diferente.

   ```
   mutation votePost {
     vote(id:123, direction: DOWN) {
       id
       author
       title
       content
       url
       ups
       downs
       version
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `votePost`.

   En esta ocasión, debería ver cómo se incrementan en `1` los campos `downs` y `version` cada vez que ejecuta la consulta.

## Configuración de un solucionador DeletePost (Amazon DynamoDB) DeleteItem
<a name="configure-deletepost"></a>

A continuación, hay que crear una mutación para eliminar una publicación. Para ello, utilizará la operación `DeleteItem` de Amazon DynamoDB.

**Para añadir su mutación**

1. En el esquema, seleccione la pestaña **Esquema**.

1. En el panel **Esquema** modifique el tipo `Mutation` para añadir una nueva mutación `deletePost`:

   ```
   type Mutation {
       deletePost(id: ID!, expectedVersion: Int): Post
       vote(id: ID!, direction: DIRECTION!): Post
       updatePost(
           id: ID!,
           author: String,
           title: String,
           content: String,
           url: String,
           expectedVersion: Int!
       ): Post
       addPost(
           id: ID
           author: String!,
           title: String!,
           content: String!,
           url: String!
       ): Post!
   }
   ```

1. Esta vez, ha hecho que el campo `expectedVersion` sea opcional. Elija **Guardar esquema**.

1. En el panel **Solucionadores** de la derecha, busque el campo `delete` recién creado en el tipo `Mutation` y, a continuación, seleccione **Asociar**. Cree un nuevo solucionador con el siguiente código:

   ```
   import { util } from '@aws-appsync/utils'
   
   import { util } from '@aws-appsync/utils';
   import * as ddb from '@aws-appsync/utils/dynamodb';
   
   export function request(ctx) {
     let condition = null;
     if (ctx.args.expectedVersion) {
       condition = {
         or: [
           { id: { attributeExists: false } },
           { version: { eq: ctx.args.expectedVersion } },
         ],
       };
     }
     return ddb.remove({ key: { id: ctx.args.id }, condition });
   }
   
   export function response(ctx) {
     const { error, result } = ctx;
     if (error) {
       util.appendError(error.message, error.type);
     }
     return result;
   }
   ```
**nota**  
El argumento `expectedVersion` es opcional. Si el intermediario ha establecido un argumento `expectedVersion` en la solicitud, entonces el controlador de solicitudes añade una condición que solo permitirá que la solicitud `DeleteItem` se atienda cuando el elemento se haya eliminado o cuando el atributo `version` de la publicación en Amazon DynamoDB coincida exactamente con `expectedVersion`. Si se omite, no se especificará ninguna expresión de condición para la solicitud `DeleteItem`. Se realizará correctamente independientemente del valor de `version` o de si el elemento existe o no en Amazon DynamoDB.  
Aunque se trate de eliminar un elemento, puede devolver el elemento eliminado, siempre que no se haya eliminado previamente.

Para obtener más información sobre la `DeleteItem` solicitud, consulte la documentación. [DeleteItem](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-deleteitem)

### Llame la API para eliminar una publicación
<a name="call-api-delete"></a>

Ahora que el solucionador está configurado, AWS AppSync sabe cómo convertir una `delete` mutación entrante en una operación de Amazon `DeleteItem` DynamoDB. Ahora ya podemos ejecutar una mutación para eliminar datos de la tabla.

**Para ejecutar su mutación**

1. En su API, seleccione la pestaña **Consultas**.

1. En el panel **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
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `deletePost`.

1. La publicación se elimina de Amazon DynamoDB. **Tenga en cuenta que AWS AppSync devuelve el valor del elemento que se eliminó de Amazon DynamoDB, que debería 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
       }
     }
   }
   ```

1. El valor solo se devuelve si esta llamada a `deletePost` es la que realmente lo elimina de Amazon DynamoDB. Vuelva a seleccionar **Ejecutar**.

1. La llamada se sigue ejecutando con éxito, pero no se devuelve ningún valor:

   ```
   {
     "data": {
       "deletePost": null
     }
   }
   ```

1. 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.

1. En el panel **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
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `addPost`.

1. Los resultados de la publicación que acaba de crear deben aparecer en el panel **Resultados** a la derecha del panel **Consultas**. Registre el `id` del objeto recién creado, pues lo necesitará 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
       }
     }
   }
   ```

1. Ahora, intentemos eliminar esa publicación con un valor ilegal para **expectedVersion**. En el panel **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
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `deletePost`. Se devuelve el siguiente resultado:

   ```
   {
     "data": {
       "deletePost": null
     },
     "errors": [
       {
         "path": [
           "deletePost"
         ],
         "data": null,
         "errorType": "DynamoDB:ConditionalCheckFailedException",
         "errorInfo": null,
         "locations": [
           {
             "line": 2,
             "column": 3,
             "sourceName": null
           }
         ],
         "message": "The conditional request failed (Service: DynamoDb, Status Code: 400, Request ID: 7083O037M1FTFRK038A4CI9H43VV4KQNSO5AEMVJF66Q9ASUAAJG)"
       }
     ]
   }
   ```

1. La solicitud ha fallado porque la expresión de condición se evalúa como `false`. El valor `version` de la publicación en Amazon DynamoDB no coincide con el `expectedValue` especificado en los argumentos. El valor actual del objeto se devuelve en el campo `data` de la sección `errors` 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
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `deletePost`. 

   Esta vez la solicitud se realiza correctamente y se devuelve el valor eliminado de Amazon 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
       }
     }
   }
   ```

1. Vuelva a seleccionar **Ejecutar**. La llamada se sigue realizando correctamente, pero esta vez no se devuelve ningún valor, ya que la publicación ya se había eliminado en Amazon DynamoDB.

   ```
   { "data": { "deletePost": null } }
   ```

## Configuración de un solucionador allPost (Scan de Amazon DynamoDB)
<a name="configure-allpost"></a>

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.

**Para añadir su mutación**

1. En su API, seleccione la pestaña **Esquema**.

1. En el panel **Schema (Esquema)** modifique el tipo `Query` para agregar una nueva consulta `allPost`, de este modo:

   ```
   type Query {
       allPost(limit: Int, nextToken: String): PaginatedPosts!
       getPost(id: ID): Post
   }
   ```

1. Añada un nuevo tipo `PaginationPosts`:

   ```
   type PaginatedPosts {
       posts: [Post!]!
       nextToken: String
   }
   ```

1. Elija **Save Schema (Guardar esquema)**.

1. En el panel **Solucionadores** de la derecha, busque el campo `allPost` recién creado en el tipo `Query` y, a continuación, seleccione **Asociar**. Cree un nuevo solucionador con el siguiente código:

   ```
   import * as ddb from '@aws-appsync/utils/dynamodb';
   
   export function request(ctx) {
     const { limit = 20, nextToken } = ctx.arguments;
     return ddb.scan({ limit, nextToken });
   }
   
   export function response(ctx) {
     const { items: posts = [], nextToken } = ctx.result;
     return { posts, nextToken };
   }
   ```

   El controlador de solicitudes de este solucionador espera dos argumentos opcionales: 
   + `limit`: especifica el número máximo de elementos que se devolverán en una sola llamada.
   + `nextToken`: se usa para recuperar el siguiente conjunto de resultados (mostraremos de dónde proviene el valor de `nextToken` más adelante).

1. Guarde los cambios realizados en el solucionador.

Si desea más información sobre la solicitud `Scan`, consulte la documentación de referencia de [Scan](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-scan).

### Llame a la API para escanear todas las publicaciones
<a name="call-api-scan"></a>

Ahora que el solucionador está configurado, AWS AppSync sabe cómo convertir una `allPost` consulta entrante en una operación de Amazon `Scan` 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.

**Para añadir y consultar datos**

1. En su API, seleccione la pestaña **Consultas**.

1. En el panel **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 }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja). 

1. Ahora recorreremos la tabla obteniendo cinco resultados cada vez. En el panel **Consultas**, añada la siguiente consulta:

   ```
   query allPost {
     allPost(limit: 5) {
       posts {
         id
         title
       }
       nextToken
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `allPost`.

   Las cinco primeras publicaciones deben aparecer en el panel **Resultados** a la derecha del panel **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": "<token>"
       }
     }
   }
   ```

1. Ha recibido cinco resultados y un `nextToken`, que permite obtener el siguiente conjunto de resultados. Actualice la consulta `allPost` para incluir el valor de `nextToken` del conjunto de resultados anterior: 

   ```
   query allPost {
     allPost(
       limit: 5
       nextToken: "<token>"
     ) {
       posts {
         id
         author
       }
       nextToken
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `allPost`.

   Las cuatro publicaciones restantes deben aparecer en el panel **Resultados** a la derecha del panel **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 de un solucionador de allPostsBy autores (Amazon DynamoDB Query)
<a name="configure-query"></a>

Además de escanear Amazon DynamoDB para obtener todas las publicaciones, también puede consultar Amazon DynamoDB para obtener las publicaciones creadas por un autor determinado. La tabla de Amazon DynamoDB que creó anteriormente ya tiene un `GlobalSecondaryIndex` llamado `author-index` que puede utilizar con una operación `Query` de Amazon DynamoDB para recuperar todas las publicaciones creadas por un autor específico.

**Para añadir su consulta**

1. En su API, seleccione la pestaña **Esquema**.

1. En el panel **Schema (Esquema)** modifique el tipo `Query` para agregar una nueva consulta `allPostsByAuthor`, de este modo:

   ```
   type Query {
       allPostsByAuthor(author: String!, limit: Int, nextToken: String): PaginatedPosts!
       allPost(limit: Int, nextToken: String): PaginatedPosts!
       getPost(id: ID): Post
   }
   ```

   Tenga en cuenta que aquí vuelve a usarse el tipo `PaginatedPosts` que empleamos con la consulta `allPost`.

1. Elija **Save Schema (Guardar esquema)**.

1. En el panel **Solucionadores** de la derecha, busque el campo `allPostsByAuthor` recién creado en el tipo `Query` y, a continuación, seleccione **Asociar**. Cree un solucionador con el siguiente fragmento:

   ```
   import * as ddb from '@aws-appsync/utils/dynamodb';
   
   export function request(ctx) {
     const { limit = 20, nextToken, author } = ctx.arguments;
     return ddb.query({
       index: 'author-index',
       query: { author: { eq: author } },
       limit,
       nextToken,
     });
   }
   
   export function response(ctx) {
     const { items: posts = [], nextToken } = ctx.result;
     return { posts, nextToken };
   }
   ```

   Al igual que el solucionador `allPost`, este solucionador tiene dos argumentos opcionales:
   + `limit`: especifica el número máximo de elementos que se devolverán en una sola llamada.
   + `nextToken`: recupera el siguiente conjunto de resultados (el valor de `nextToken` puede obtenerse de una llamada anterior).

1. Guarde los cambios realizados en el solucionador.

Si desea más información sobre la solicitud `Query`, consulte la documentación de referencia de [Query](https://docs.aws.amazon.com/appsync/latest/devguide/js-resolver-reference-dynamodb.html#js-aws-appsync-resolver-reference-dynamodb-query).

### Llame a la API para consultar todas las publicaciones de un autor
<a name="call-api-query"></a>

Ahora que el solucionador está configurado, AWS AppSync sabe cómo traducir una `allPostsByAuthor` mutación entrante en una operación de `Query` DynamoDB contra el í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.

**Para añadir datos y consultas**

1. En su API, seleccione la pestaña **Consultas**.

1. En el panel **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 }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `addPost`.

1. Ahora consultaremos la tabla para que devuelva todas las publicaciones creadas por `Nadia`. En el panel **Consultas**, añada la siguiente consulta: 

   ```
   query allPostsByAuthor {
     allPostsByAuthor(author: "Nadia") {
       posts {
         id
         title
       }
       nextToken
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `allPostsByAuthor`. Todas las publicaciones creadas por `Nadia` deben aparecer en el panel **Resultados** a la derecha del panel **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
       }
     }
   }
   ```

1. 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.

1. En el panel **Consultas**, añada la siguiente consulta: 

   ```
   query allPostsByAuthor {
     allPostsByAuthor(
       author: "AUTHORNAME"
       limit: 5
     ) {
       posts {
         id
         title
       }
       nextToken
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `allPostsByAuthor`. Todas las publicaciones creadas por `AUTHORNAME` deben aparecer en el panel **Resultados** a la derecha del panel **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": "<token>"
       }
     }
   }
   ```

1. Actualice el argumento `nextToken` con el valor devuelto en la consulta anterior, de este modo:

   ```
   query allPostsByAuthor {
     allPostsByAuthor(
       author: "AUTHORNAME"
       limit: 5
       nextToken: "<token>"
     ) {
       posts {
         id
         title
       }
       nextToken
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `allPostsByAuthor`. Las demás publicaciones creadas por `AUTHORNAME` deben aparecer en el panel **Resultados** a la derecha del panel **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
<a name="using-sets"></a>

Hasta este punto, el `Post` tipo era un objeto plano key/value . El solucionador 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.

**Para configurar sus datos**

1. En su API, seleccione la pestaña **Esquema**. 

1. En el panel **Schema (Esquema)** modifique el tipo `Post` para agregar un nuevo campo `tags`, de este modo:

   ```
   type Post {
     id: ID!
     author: String
     title: String
     content: String
     url: String
     ups: Int!
     downs: Int!
     version: Int!
     tags: [String!]
   }
   ```

1. En el panel **Schema (Esquema)** modifique el tipo `Query` para agregar una nueva consulta `allPostsByTag`, de este modo:

   ```
   type Query {
     allPostsByTag(tag: String!, limit: Int, nextToken: String): PaginatedPosts!
     allPostsByAuthor(author: String!, limit: Int, nextToken: String): PaginatedPosts!
     allPost(limit: Int, nextToken: String): PaginatedPosts!
     getPost(id: ID): Post
   }
   ```

1. En el panel **Schema (Schema)**, modifique el tipo `Mutation` para agregar las nuevas mutaciones `addTag` y `removeTag`, 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!
   }
   ```

1. Elija **Save Schema (Guardar esquema)**.

1. En el panel **Solucionadores** de la derecha, busque el campo `allPostsByTag` recién creado en el tipo `Query` y, a continuación, seleccione **Asociar**. Cree su solucionador con el siguiente fragmento:

   ```
   import * as ddb from '@aws-appsync/utils/dynamodb';
   
   export function request(ctx) {
     const { limit = 20, nextToken, tag } = ctx.arguments;
     return ddb.scan({ limit, nextToken, filter: { tags: { contains: tag } } });
   }
   
   export function response(ctx) {
     const { items: posts = [], nextToken } = ctx.result;
     return { posts, nextToken };
   }
   ```

1. Guarde los cambios que haya realizado en el solucionador.

1. Ahora, haga lo mismo con el campo `addTag` de `Mutation` usando el siguiente fragmento:
**nota**  
Aunque las utilidades de DynamoDB actualmente no admiten operaciones de conjuntos, puede interactuar con los conjuntos creando la solicitud usted mismo.

   ```
   import { util } from '@aws-appsync/utils'
   
   export function request(ctx) {
   	const { id, tag } = ctx.arguments
   	const expressionValues = util.dynamodb.toMapValues({ ':plusOne': 1 })
   	expressionValues[':tags'] = util.dynamodb.toStringSet([tag])
   
   	return {
   		operation: 'UpdateItem',
   		key: util.dynamodb.toMapValues({ id }),
   		update: {
   			expression: `ADD tags :tags, version :plusOne`,
   			expressionValues,
   		},
   	}
   }
   
   export const response = (ctx) => ctx.result
   ```

1. Guarde los cambios realizados en el solucionador.

1. Repita esta operación una vez más para el campo `removeTag` de `Mutation` utilizando el siguiente fragmento:

   ```
   import { util } from '@aws-appsync/utils';
   	
   export function request(ctx) {
   	  const { id, tag } = ctx.arguments;
   	  const expressionValues = util.dynamodb.toMapValues({ ':plusOne': 1 });
   	  expressionValues[':tags'] = util.dynamodb.toStringSet([tag]);
   	
   	  return {
   	    operation: 'UpdateItem',
   	    key: util.dynamodb.toMapValues({ id }),
   	    update: {
   	      expression: `DELETE tags :tags ADD version :plusOne`,
   	      expressionValues,
   	    },
   	  };
   	}
   	
   	export const response = (ctx) => ctx.resultexport
   ```

1. Guarde los cambios realizados en el solucionador.

### Llame a la API para trabajar con etiquetas
<a name="call-api-tags"></a>

Ahora que ha configurado los resolutores, AWS AppSync sabe cómo traducir las solicitudes entrantes `addTag` y las `allPostsByTag` solicitudes a `UpdateItem` DynamoDB `Scan` y a las operaciones. `removeTag` Para probarlo, vamos a seleccionar una de las publicaciones que ha creado anteriormente. Por ejemplo, tomemos una publicación creada por `Nadia`.

**Para usar etiquetas**

1. En su API, seleccione la pestaña **Consultas**.

1. En el panel **Consultas**, añada la siguiente consulta:

   ```
   query allPostsByAuthor {
     allPostsByAuthor(
       author: "Nadia"
     ) {
       posts {
         id
         title
       }
       nextToken
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `allPostsByAuthor`.

1. Todas las publicaciones de Nadia deben aparecer en el panel **Resultados** a la derecha del panel **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
       }
     }
   }
   ```

1. Usemos el que tiene el título *The cutest dog in the world*. Registre su `id`, ya que vamos a utilizarlo más adelante. Ahora probemos a añadirle la etiqueta `dog`.

1. En el panel **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
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `addTag`. La publicación se actualiza con la nueva etiqueta:

   ```
   {
     "data": {
       "addTag": {
         "id": "10",
         "title": "The cutest dog in the world",
         "tags": [
           "dog"
         ]
       }
     }
   }
   ```

1. Puede añadir más etiquetas. Actualice la mutación para cambiar el argumento `tag` a `puppy`:

   ```
   mutation addTag {
     addTag(id:10 tag: "puppy") {
       id
       title
       tags
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `addTag`. La publicación se actualiza con la nueva etiqueta:

   ```
   {
     "data": {
       "addTag": {
         "id": "10",
         "title": "The cutest dog in the world",
         "tags": [
           "dog",
           "puppy"
         ]
       }
     }
   }
   ```

1. También puede eliminar etiquetas. En el panel **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
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `removeTag`. La publicación se actualiza y la etiqueta `puppy` se elimina.

   ```
   {
     "data": {
       "addTag": {
         "id": "10",
         "title": "The cutest dog in the world",
         "tags": [
           "dog"
         ]
       }
     }
   }
   ```

1. También puede buscar todas las publicaciones que tengan una etiqueta. En el panel **Consultas**, añada la siguiente consulta: 

   ```
   query allPostsByTag {
     allPostsByTag(tag: "dog") {
       posts {
         id
         title
         tags
       }
       nextToken
     }
   }
   ```

1. Seleccione **Ejecutar** (el botón de reproducción naranja) y, a continuación, elija `allPostsByTag`. 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
       }
     }
   }
   ```

## Conclusión
<a name="conclusion-dynamodb-tutorial-js"></a>

En este tutorial ha creado una API que nos permite manipular objetos `Post` en DynamoDB mediante AWS AppSync y GraphQL. 

Para limpiar, puedes eliminar la API de AWS AppSync GraphQL de la consola. 

Para eliminar el rol asociado a la tabla de DynamoDB, seleccione el origen de datos en la tabla **Orígenes de datos** y haga clic en **Editar**. Anote el valor del rol en **Crear o usar un rol existente**. Vaya a la consola de IAM para eliminar el rol.

Para eliminar la tabla de DynamoDB, haga clic en el nombre de la tabla en la lista de orígenes de datos. Esto le llevará a la consola de DynamoDB, donde podrá eliminar la tabla. 