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 API de AWS AppSync con el AWS CDK
sugerencia
Antes de usar el CDK, le recomendamos que consulte la documentación oficial de este, junto con la referencia del CDK de AWS AppSync.
También recomendamos asegurarse de que las instalaciones de la CLI de AWS y NPM
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 pretende que sea un ejemplo rápido en el que se utiliza parte del código de las secciones Diseño del esquema, Asociar un origen de datos y Configuración de solucionadores (JavaScript).
Configuración de un proyecto de CDK
aviso
Es posible que estos pasos no sean completamente precisos en función del entorno. Se da por hecho que su sistema tiene instaladas las utilidades necesarias, dispone de una forma de interactuar con los servicios de AWS y tiene las configuraciones adecuadas.
El primer paso es instalar el CDK de AWS. 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 principalmente TypeScript. 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:

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

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 pondrá en marcha en AWS CloudFormation cuando se implemente 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 comandonpm
.
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í. 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:

Esto se hace una vez por cuenta y región, por lo que no tendrá que hacerlo con frecuencia. Los recursos principales del arranque son la pila de AWS CloudFormation 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 pila de AWS CloudFormation, denominada pila de arranque, que suele tener el nombre CDKToolkit
. Como cualquier pila de AWS CloudFormation, aparece en la consola de AWS CloudFormation una vez implementada:

Lo mismo puede decirse del bucket:

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
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
:

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:

Parece que nuestro ejemplo se ha ejecutado correctamente, pero revisemos la consola de AWS AppSync para confirmarlo:

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

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 pila de AWS CloudFormation:

Cuando implementamos nuestra aplicación de CDK, pasa por AWS CloudFormation para activar recursos, como el arranque. Cada pila de nuestra aplicación se asigna con una correspondencia de 1:1 a una pila de AWS CloudFormation. Si vuelve al código de la pila, verá que el nombre de la pila se ha tomado del nombre de la claseExampleCdkAppStack
. 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:

Implementación de un proyecto de CDK: origen de datos
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:

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

Implementación de un proyecto de CDK: solucionador
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 añadirlo al servicio de AWS AppSync:
cdk deploy
Comprobemos la consola de AWS AppSync para ver si estaban asociados a nuestra API de GraphQL:

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
:

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:

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:

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

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

Ahora, necesitamos probar este código realizando algunas solicitudes.
Implementación de un proyecto de CDK: solicitudes
Para probar nuestra aplicación en la consola de AWS AppSync, creamos una consulta y una mutación:

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:

De vuelta en la consola de AWS AppSync, si ejecutamos la consulta para recuperar este Post
, obtenemos el siguiente resultado:
{ "data": { "getPost": [ { "id": "9f62c4dd-49d5-48d5-b835-143284c72fe0", "date": "1970-01-01T12:30:00.000Z", "title": "first post" } ] } }