

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.

# Uso de una AWS AppSync API con el AWS CDK
<a name="using-your-api"></a>

**sugerencia**  
[Antes de usar la CDK, te recomendamos que consultes la [documentación oficial](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html) de la CDK junto con AWS AppSync su referencia.](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.aws_appsync-readme.html)  
También recomendamos asegurarse de que las instalaciones de la [CLI de AWS](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) y [NPM](https://docs.npmjs.com/) funcionan en el sistema.

En esta sección, vamos a crear una aplicación de CDK sencilla que pueda añadir y obtener elementos de una tabla de DynamoDB. Se trata de un ejemplo de inicio rápido en el que se utiliza parte del código de las secciones [Diseñar un esquema](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html), [Adjuntar una fuente de datos](https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.html) y [Configurar](https://docs.aws.amazon.com/appsync/latest/devguide/configuring-resolvers-js.html) resolutores (). JavaScript

## Configuración de un proyecto de CDK
<a name="Setting-up-a-cdk-project"></a>

**aviso**  
Es posible que estos pasos no sean completamente precisos en función del entorno. Suponemos que su sistema tiene instaladas las utilidades necesarias, una forma de interactuar con AWS los servicios y las configuraciones adecuadas.

El primer paso es instalar el AWS CDK. En su CLI, puede introducir el comando siguiente:

```
npm install -g aws-cdk
```

A continuación, debe crear un directorio del proyecto y, luego, navegar hasta él. Un ejemplo de un conjunto de comandos para crear un directorio y navegar a él es:

```
mkdir example-cdk-app
cd example-cdk-app
```

A continuación, debe crear una aplicación. Nuestro servicio utiliza TypeScript principalmente. Ejecute el siguiente comando en el directorio de su proyecto:

```
cdk init app --language typescript
```

Al hacerlo, se instalará una aplicación CDK junto con sus archivos de inicialización:

![Salida de terminal que muestra la inicialización del repositorio de Git con sugerencias de nomenclatura de la rama maestra.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-init-app-example.png)


La estructura de proyecto puede tener un aspecto similar al siguiente:

![Árbol de archivos que muestra el example-cdk-app proyecto con bin, lib, node_modules, carpetas de prueba y archivos de configuración.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-init-directories.png)


Se dará cuenta de que tenemos varios directorios importantes:
+ `bin`: el archivo bin inicial creará la aplicación. No trataremos este tema en esta guía.
+ `lib`: el directorio lib contiene los archivos de pila. Los archivos de pila se podrían comparar a unidades de ejecución individuales. Las construcciones estarán dentro de nuestros archivos de pila. Básicamente, se trata de recursos para un servicio que se activará CloudFormation cuando se despliegue la aplicación. Aquí es donde se realizará la mayor parte de nuestra codificación.
+ `node_modules`: este directorio lo creó NPM y contiene todas las dependencias de paquetes que instaló mediante el comando `npm`.

Nuestro archivo de pila inicial puede contener algo como esto:

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
// import * as sqs from 'aws-cdk-lib/aws-sqs';

export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // The code that defines your stack goes here

    // example resource
    // const queue = new sqs.Queue(this, 'ExampleCdkAppQueue', {
    //   visibilityTimeout: cdk.Duration.seconds(300)
    // });
  }
}
```

Este es el código reutilizable para crear una pila en nuestra aplicación. La mayor parte del código de este ejemplo se incluirá en el ámbito de esta clase.

Para comprobar que el archivo de pila está en la aplicación, en el directorio de la aplicación, ejecute el siguiente comando en el terminal:

```
cdk ls
```

Debería aparecer una lista de sus pilas. Si no es así, es posible que tenga que volver a realizar los pasos o consultar la documentación oficial para obtener ayuda.

Si quiere compilar los cambios de código antes de implementarlos, siempre puede ejecutar el siguiente comando en el terminal:

```
npm run build
```

Y, para ver los cambios antes de la implementación:

```
cdk diff
```

Antes de añadir nuestro código al archivo de pila, vamos a realizar un arranque. El arranque nos permite aprovisionar recursos para el CDK antes de que se implemente la aplicación. Puede encontrar más información sobre este proceso [aquí](https://docs.aws.amazon.com/cdk/v2/guide/bootstrapping.html). El comando para crear un arranque es:

```
cdk bootstrap aws://ACCOUNT-NUMBER/REGION
```

**sugerencia**  
Este paso requiere varios permisos de IAM en su cuenta. Se denegará el arranque si no los tiene. Si esto ocurre, es posible que tenga que eliminar los recursos incompletos que ha causado el arranque, como el bucket de S3 que genera.

El arranque generará varios recursos. El mensaje final tendrá el siguiente aspecto:

![La salida del terminal muestra el mensaje de arranque del entorno tras CloudFormation la creación del conjunto de cambios.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-init-bootstrap-final.png)


Esto se hace una vez por cuenta y región, por lo que no tendrá que hacerlo con frecuencia. Los principales recursos del bootstrap son la CloudFormation pila y el bucket de Amazon S3.

El bucket de Amazon S3 se utiliza para almacenar archivos y roles de IAM que conceden los permisos necesarios para realizar las implementaciones. Los recursos necesarios se definen en una CloudFormation pila, denominada pila bootstrap, que suele tener ese nombre. `CDKToolkit` Como cualquier CloudFormation pila, aparece en la CloudFormation consola una vez desplegada:

![CloudFormation consola que muestra la CDKToolkit pila con el estado CREATE_COMPLETE.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-init-bootstrap-cfn-console.png)


Lo mismo puede decirse del bucket:

![Fila de compartimentos S3 que muestra el nombre, la región de Oregón Occidental (EE. UU.), el acceso privado y la fecha de creación.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-init-bootstrap-bucket-console.png)


Para importar los servicios que necesitamos en nuestro archivo de pila, podemos usar el siguiente comando:

```
npm install aws-cdk-lib # V2 command
```

**sugerencia**  
Si tiene problemas con la V2, puede instalar las bibliotecas individuales mediante los comandos de la V1:  

```
npm install @aws-cdk/aws-appsync @aws-cdk/aws-dynamodb
```
No recomendamos esta opción porque la V1 está en desuso.

## Implementación de un proyecto de CDK: esquema
<a name="implementing-a-cdk-project-schema"></a>

Ahora podemos empezar a implementar nuestro código. En primer lugar, debemos crear nuestro esquema. Simplemente puede crear un archivo `.graphql` en su aplicación:

```
mkdir schema
touch schema.graphql
```

En nuestro ejemplo, incluimos un directorio de nivel superior llamado `schema` que contiene nuestro `schema.graphql`:

![El árbol de archivos muestra la carpeta del esquema expandida con el archivo schema.graphql resaltado.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-schema-directory.png)


Dentro de nuestro esquema, vamos a incluir un ejemplo sencillo:

```
input CreatePostInput {
    title: String
    content: String
}

type Post {
    id: ID!
    title: String
    content: String
}

type Mutation {
    createPost(input: CreatePostInput!): Post
}

type Query {
    getPost: [Post]
}
```

De vuelta a nuestro archivo de pila, debemos asegurarnos de que estén definidas las siguientes directivas de importación:

```
import * as cdk from 'aws-cdk-lib';
import * as appsync from 'aws-cdk-lib/aws-appsync';
import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
import { Construct } from 'constructs';
```

Dentro de la clase, añadiremos código para crear nuestra API de GraphQL y conectarla a nuestro archivo `schema.graphql`:

```
export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    
    // makes a GraphQL API
    const api = new appsync.GraphqlApi(this, 'post-apis', {
      name: 'api-to-process-posts',
      schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'),
    });
  }
}
```

También añadiremos código para imprimir la URL de GraphQL, la clave de API y la región:

```
export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);
    
    // Makes a GraphQL API construct
    const api = new appsync.GraphqlApi(this, 'post-apis', {
      name: 'api-to-process-posts',
      schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'),
    });

    // Prints out URL
    new cdk.CfnOutput(this, "GraphQLAPIURL", {
      value: api.graphqlUrl
    });

    // Prints out the AppSync GraphQL API key to the terminal
    new cdk.CfnOutput(this, "GraphQLAPIKey", {
      value: api.apiKey || ''
    });

    // Prints out the stack region to the terminal
    new cdk.CfnOutput(this, "Stack Region", {
      value: this.region
    });
  }
}
```

En este punto, volveremos a implementar nuestra aplicación:

```
cdk deploy
```

El resultado es el siguiente:

![CDK resultado de despliegue que muestra la clave de la API de GraphQL, la URL, la región de la pila y los detalles del ARN.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-schema.png)


Parece que nuestro ejemplo fue exitoso, pero revisemos la AWS AppSync consola para confirmarlo:

![La navegación de la consola se muestra api-to-process-posts con la opción GraphQL y API_KEY se muestra.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-schema-result-1.png)


Parece que nuestra API se ha creado. Ahora, comprobaremos el esquema asociado a la API:

![Esquema de GraphQL que muestra CreatePostInput las definiciones de tipo de publicación, mutación y consulta.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-schema-result-2.png)


Esto parece coincidir con nuestro código de esquema, por lo que se ha realizado correctamente. Otra forma de confirmarlo desde el punto de vista de los metadatos es observar la CloudFormation pila:

![CloudFormation lista de pilas ExampleCdkAppStack con los estados UPDATE_COMPLETE y CDKToolkit CREATE_COMPLETE.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-schema-result-3.png)


Cuando implementamos nuestra aplicación CDK, esta activa recursos, como el CloudFormation bootstrap. Cada pila de nuestra aplicación se mapea 1:1 con una CloudFormation pila. Si vuelve al código de la pila, verá que el nombre de la pila se ha tomado del nombre de la clase`ExampleCdkAppStack`. Puede ver los recursos que creó, que también se ajustan a nuestras convenciones de nomenclatura, en nuestra construcción de la API de GraphQL:

![Vista de árbol colapsada que muestra las aplicaciones posteriores con los CDKMetadata elementos del esquema y DefaultApiKey, y.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-schema-result-4.png)


## Implementación de un proyecto de CDK: origen de datos
<a name="implementing-a-cdk-project-data-source"></a>

A continuación, debemos añadir nuestro origen de datos. En nuestro ejemplo, se utilizará una tabla de DynamoDB. Dentro de la clase de pila, añadiremos código para crear una tabla nueva:

```
export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Makes a GraphQL API construct
    const api = new appsync.GraphqlApi(this, 'post-apis', {
      name: 'api-to-process-posts',
      schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'),
    });

    //creates a DDB table
    const add_ddb_table = new dynamodb.Table(this, 'posts-table', {
      partitionKey: {
        name: 'id',
        type: dynamodb.AttributeType.STRING,
      },
    });

    // Prints out URL
    new cdk.CfnOutput(this, "GraphQLAPIURL", {
      value: api.graphqlUrl
    });

    // Prints out the AppSync GraphQL API key to the terminal
    new cdk.CfnOutput(this, "GraphQLAPIKey", {
      value: api.apiKey || ''
    });

    // Prints out the stack region to the terminal
    new cdk.CfnOutput(this, "Stack Region", {
      value: this.region
    });
  }
}
```

Llegados a este punto, volvamos a implementarla:

```
cdk deploy
```

Deberíamos comprobar la consola de DynamoDB para ver nuestra nueva tabla:

![DynamoDB fila de la tabla que muestra ExampleCdkAppStack -postable con el estado Activo y la clase Estándar.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-ddb-result-1.png)


El nombre de nuestra pila es correcto y el nombre de la tabla coincide con nuestro código. Si volvemos a revisar nuestra CloudFormation pila, ahora veremos la nueva tabla:

![Jerarquía de ID lógica que muestra post-apis, posts-table, postStableC6b5a2e6 y. CDKMetadata](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-ddb-result-2.png)


## Implementación de un proyecto de CDK: solucionador
<a name="implementing-a-cdk-project-resolver"></a>

En este ejemplo, se utilizarán dos solucionadores: uno para consultar la tabla y otro para añadirle elementos. Como utilizamos solucionadores de canalizaciones, tendremos que declarar dos solucionadores de canalizaciones con una función en cada uno. En la consulta, añadiremos el siguiente código:

```
export class ExampleCdkAppStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    // Makes a GraphQL API construct
    const api = new appsync.GraphqlApi(this, 'post-apis', {
      name: 'api-to-process-posts',
      schema: appsync.SchemaFile.fromAsset('schema/schema.graphql'),
    });

    //creates a DDB table
    const add_ddb_table = new dynamodb.Table(this, 'posts-table', {
      partitionKey: {
        name: 'id',
        type: dynamodb.AttributeType.STRING,
      },
    });

    // Creates a function for query
    const add_func = new appsync.AppsyncFunction(this, 'func-get-post', {
      name: 'get_posts_func_1',
      api,
      dataSource: api.addDynamoDbDataSource('table-for-posts', add_ddb_table),
      code: appsync.Code.fromInline(`
          export function request(ctx) {
          return { operation: 'Scan' };
          }

          export function response(ctx) {
          return ctx.result.items;
          }
  `),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
    });

    // Creates a function for mutation
    const add_func_2 = new appsync.AppsyncFunction(this, 'func-add-post', {
      name: 'add_posts_func_1',
      api,
      dataSource: api.addDynamoDbDataSource('table-for-posts-2', add_ddb_table),
      code: appsync.Code.fromInline(`
          export function request(ctx) {
            return {
            operation: 'PutItem',
            key: util.dynamodb.toMapValues({id: util.autoId()}),
            attributeValues: util.dynamodb.toMapValues(ctx.args.input),
            };
          }

          export function response(ctx) {
            return ctx.result;
          }
      `),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
    });

    // Adds a pipeline resolver with the get function
    new appsync.Resolver(this, 'pipeline-resolver-get-posts', {
      api,
      typeName: 'Query',
      fieldName: 'getPost',
      code: appsync.Code.fromInline(`
          export function request(ctx) {
          return {};
          }

          export function response(ctx) {
          return ctx.prev.result;
          }
  `),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
      pipelineConfig: [add_func],
    });

    // Adds a pipeline resolver with the create function
    new appsync.Resolver(this, 'pipeline-resolver-create-posts', {
      api,
      typeName: 'Mutation',
      fieldName: 'createPost',
      code: appsync.Code.fromInline(`
          export function request(ctx) {
          return {};
          }

          export function response(ctx) {
          return ctx.prev.result;
          }
  `),
      runtime: appsync.FunctionRuntime.JS_1_0_0,
      pipelineConfig: [add_func_2],
    });

    // Prints out URL
    new cdk.CfnOutput(this, "GraphQLAPIURL", {
      value: api.graphqlUrl
    });

    // Prints out the AppSync GraphQL API key to the terminal
    new cdk.CfnOutput(this, "GraphQLAPIKey", {
      value: api.apiKey || ''
    });

    // Prints out the stack region to the terminal
    new cdk.CfnOutput(this, "Stack Region", {
      value: this.region
    });
  }
}
```

En este fragmento, añadimos un solucionador de canalizaciones llamado `pipeline-resolver-create-posts` con una función llamada `func-add-post` asociada. Este es el código que añadirá `Posts` a la tabla. El otro solucionador de canalizaciones se ha denominado `pipeline-resolver-get-posts`, con una función llamada `func-get-post` que recupera `Posts` añadidos a la tabla.

Implementaremos esto para agregarlo al servicio AWS AppSync :

```
cdk deploy
```

Comprobemos la AWS AppSync consola para ver si estaban conectadas a nuestra API GraphQL:

![Campos de mutación y consulta que muestran las resoluciones CreatePost y GetPost vinculadas a Pipeline.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-1.png)


Parece correcto. En el código, estos dos solucionadores estaban conectados a la API de GraphQL que creamos (indicada por el valor de accesorios `api` presente tanto en los solucionadores como en las funciones). En la API de GraphQL, los campos a los que asociamos nuestros solucionadores también estaban especificados en los accesorios (definidos por `typename` y los accesorios `fieldname` de cada solucionador).

Veamos si el contenido de los solucionadores es correcto empezando por `pipeline-resolver-get-posts`:

![Código de resolución que muestra las funciones de solicitud y respuesta con una flecha que apunta a la función de respuesta.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-2.png)


Los controladores de antes y después coinciden con nuestro valor de accesorios `code`. También podemos ver una función llamada `add_posts_func_1`, que coincide con el nombre de la función que asociamos en el solucionador.

Veamos el contenido del código de esa función:

![Fragmento de código que muestra las funciones de solicitud y respuesta con valores de operación, clave y atributo.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-3.png)


Esto coincide con los accesorios `code` de la función `add_posts_func_1`. Nuestra consulta se ha cargado correctamente, así que revisemos la consulta:

![Código de resolución que muestra la función de respuesta con una flecha que apunta a la función get_posts_func_1 a continuación.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-4.png)


También coinciden con el código. Si nos fijamos en `get_posts_func_1`:

![El código de función muestra la función de solicitud que devuelve la operación de escaneo y la función de respuesta que devuelve ctx.result.items.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-5.png)


Todo parece estar en su sitio. Para confirmarlo desde el punto de vista de los metadatos, podemos volver a revisar nuestra pila en CloudFormation :

![Lista de lógica que IDs incluye postapis, posts-table, funciones, solucionadores de canalizaciones y. CDKMetadata](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-deploy-resolver-result-6.png)


Ahora, necesitamos probar este código realizando algunas solicitudes.

## Implementación de un proyecto de CDK: solicitudes
<a name="implementing-a-cdk-project-requests"></a>

Para probar nuestra aplicación en la AWS AppSync consola, hicimos una consulta y una mutación:

![El código GraphQL se muestra con los campos MyQuery GetPost y MyMutation con la operación CreatePost.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-request-1.png)


`MyMutation` contiene una operación `createPost` con los argumentos `1970-01-01T12:30:00.000Z` y `first post`. Devuelve los `date` y `title` que hemos introducido, así como el valor `id` generado automáticamente. Al ejecutar la mutación, se obtiene el resultado:

```
{
  "data": {
    "createPost": {
      "date": "1970-01-01T12:30:00.000Z",
      "id": "4dc1c2dd-0aa3-4055-9eca-7c140062ada2",
      "title": "first post"
    }
  }
}
```

Si comprobamos rápidamente la tabla de DynamoDB, podemos ver nuestra entrada en la tabla cuando la escaneamos:

![DynamoDB entrada de tabla que muestra la identificación, la fecha del 1 de enero de 1970 y el título de la primera publicación.](http://docs.aws.amazon.com/es_es/appsync/latest/devguide/images/cdk-code-request-2.png)


De vuelta a la AWS AppSync consola, si ejecutamos la consulta para recuperar esto`Post`, obtenemos el siguiente resultado:

```
{
  "data": {
    "getPost": [
      {
        "id": "9f62c4dd-49d5-48d5-b835-143284c72fe0",
        "date": "1970-01-01T12:30:00.000Z",
        "title": "first post"
      }
    ]
  }
}
```