En utilisant AWS AppSync API et avec AWS CDK - AWS AppSync

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

En utilisant AWS AppSync API et avec AWS CDK

Astuce

Avant de l'utiliserCDK, nous vous recommandons CDK de consulter la documentation officielle ainsi que AWS AppSync les CDKréférences.

Nous vous recommandons également de vous assurer que votre NPMinstallation AWS CLIet celle de votre système fonctionnent correctement.

Dans cette section, nous allons créer une CDK application simple capable d'ajouter et de récupérer des éléments à partir d'une table DynamoDB. Il s'agit d'un exemple de démarrage rapide utilisant une partie du code des sections Conception de votre schéma, Attachement d'une source de données et Configuration des résolveurs (JavaScript).

Configuration d'un CDK projet

Avertissement

Ces étapes peuvent ne pas être totalement précises en fonction de votre environnement. Nous partons du principe que les utilitaires nécessaires sont installés sur votre système, qu'il existe un moyen d'interfacer avec les AWS services et que les configurations appropriées sont en place.

La première étape consiste à installer le AWS CDK. Dans votreCLI, vous pouvez saisir la commande suivante :

npm install -g aws-cdk

Ensuite, vous devez créer un répertoire de projet, puis y accéder. Voici un exemple d'ensemble de commandes permettant de créer un répertoire et d'y accéder :

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

Ensuite, vous devez créer une application. Notre service utilise principalement TypeScript. Dans le répertoire de votre projet, entrez la commande suivante :

cdk init app --language typescript

Dans ce cas, une CDK application ainsi que ses fichiers d'initialisation seront installés :

Terminal output showing Git repository initialization and npm install completion.

La structure de votre projet peut ressembler à ceci :

Project directory structure showing folders and files for an example CDK app.

Vous remarquerez que nous avons plusieurs annuaires importants :

  • bin: Le fichier bin initial créera l'application. Nous n'aborderons pas cela dans ce guide.

  • lib: Le répertoire lib contient vos fichiers de pile. Vous pouvez considérer les fichiers de pile comme des unités d'exécution individuelles. Les constructions se trouveront dans nos fichiers de pile. Il s'agit essentiellement de ressources pour un service qui sera intégré AWS CloudFormation lors du déploiement de l'application. C'est là que se déroulera la majeure partie de notre codage.

  • node_modules: Ce répertoire est créé par NPM et contient toutes les dépendances du package que vous avez installées à l'aide de la npm commande.

Notre fichier de pile initial peut contenir quelque chose comme ceci :

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) // }); } }

Il s'agit du code standard pour créer une pile dans notre application. Dans cet exemple, la majeure partie de notre code entrera dans le champ d'application de cette classe.

Pour vérifier que votre fichier de pile se trouve bien dans l'application, dans le répertoire de votre application, exécutez la commande suivante dans le terminal :

cdk ls

Une liste de vos piles devrait apparaître. Si ce n'est pas le cas, vous devrez peut-être recommencer les étapes ou consulter la documentation officielle pour obtenir de l'aide.

Si vous souhaitez créer vos modifications de code avant le déploiement, vous pouvez toujours exécuter la commande suivante dans le terminal :

npm run build

Et pour voir les modifications avant le déploiement :

cdk diff

Avant d'ajouter notre code au fichier de pile, nous allons effectuer un bootstrap. Le bootstrapping nous permet de fournir des ressources CDK avant le déploiement de l'application. Vous trouverez plus d'informations sur ce processus ici. Pour créer un bootstrap, la commande est la suivante :

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

Cette étape nécessite plusieurs IAM autorisations dans votre compte. Votre bootstrap sera refusé si vous ne les avez pas. Dans ce cas, vous devrez peut-être supprimer les ressources incomplètes causées par le bootstrap, telles que le compartiment S3 qu'il génère.

Bootstrap lancera plusieurs ressources. Le message final ressemblera à ceci :

Terminal output showing successful bootstrapping of an AWS environment.

Cela se fait une fois par compte et par région, vous n'aurez donc pas à le faire souvent. Les principales ressources du bootstrap sont la AWS CloudFormation pile et le compartiment Amazon S3.

Le compartiment Amazon S3 est utilisé pour stocker les fichiers et les IAM rôles qui accordent les autorisations nécessaires pour effectuer des déploiements. Les ressources requises sont définies dans une AWS CloudFormation pile, appelée pile bootstrap, qui est généralement nomméeCDKToolkit. Comme toute AWS CloudFormation pile, elle apparaît dans la AWS CloudFormation console une fois déployée :

CDKToolkit stack with CREATE_COMPLETE status in AWS CloudFormation console.

Il en va de même pour le bucket :

S3 bucket details showing name, region, access settings, and creation date.

Pour importer les services dont nous avons besoin dans notre fichier de pile, nous pouvons utiliser la commande suivante :

npm install aws-cdk-lib # V2 command
Astuce

Si vous rencontrez des problèmes avec la V2, vous pouvez installer les bibliothèques individuelles à l'aide des commandes V1 :

npm install @aws-cdk/aws-appsync @aws-cdk/aws-dynamodb

Nous ne le recommandons pas car la V1 est obsolète.

Implémentation d'un CDK projet - Schéma

Nous pouvons maintenant commencer à implémenter notre code. Nous devons d'abord créer notre schéma. Vous pouvez simplement créer un .graphql fichier dans votre application :

mkdir schema touch schema.graphql

Dans notre exemple, nous avons inclus un répertoire de premier niveau appelé schema contenant : schema.graphql

File structure showing a schema folder containing schema.graphql file.

Dans notre schéma, incluons un exemple simple :

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 retour dans notre fichier de pile, nous devons nous assurer que les directives d'importation suivantes sont définies :

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';

Dans la classe, nous allons ajouter du code pour créer notre GraphQL API et le connecter à notre schema.graphql fichier :

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'), }); } }

Nous ajouterons également du code pour imprimer le GraphQLURL, la API clé et la région :

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 }); } }

À ce stade, nous allons à nouveau utiliser Deploy notre application :

cdk deploy

Voici le résultat :

Deployment output showing ExampleCdkAppStack details, including GraphQL API URL and stack region.

Il semble que notre exemple soit réussi, mais vérifions la AWS AppSync console juste pour confirmer :

GraphQL interface showing successful API request with response data displayed.

Il semblerait que le nôtre API ait été créé. Maintenant, nous allons vérifier le schéma joint au API :

GraphQL schema defining CreatePostInput, Post type, Mutation, and Query operations.

Cela semble correspondre à notre code de schéma, c'est donc un succès. Une autre façon de le confirmer du point de vue des métadonnées consiste à examiner la AWS CloudFormation pile :

AWS CloudFormation stack showing ExampleCdkAppStack update complete and CDKToolkit creation complete.

Lorsque nous déployons notre CDK application, elle fait appel AWS CloudFormation à des ressources telles que le bootstrap. Chaque pile de notre application correspond à une AWS CloudFormation pile à l'échelle 1:1. Si vous revenez au code de la pile, le nom de la pile a été extrait du nom de la classeExampleCdkAppStack. Vous pouvez voir les ressources qu'il a créées, qui correspondent également à nos conventions de dénomination dans notre structure GraphQL API :

Expanded view of post-apis resource showing Schema, DefaultApiKey, and CDKMetadata.

Mise en œuvre d'un CDK projet - Source de données

Ensuite, nous devons ajouter notre source de données. Notre exemple utilisera une table DynamoDB. Dans la classe stack, nous allons ajouter du code pour créer une nouvelle table :

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 }); } }

À ce stade, déployons à nouveau :

cdk deploy

Nous devrions vérifier la console DynamoDB pour trouver notre nouvelle table :

DynamoDB console showing ExampleCdkAppStack-poststable as Active with Provisioned capacity.

Le nom de notre pile est correct et le nom de la table correspond à notre code. Si nous vérifions à nouveau notre AWS CloudFormation pile, nous verrons maintenant le nouveau tableau :

Expanded view of a logical ID in AWS CloudFormation showing post-apis, posts-table, and CDKMetadata.

Implémentation d'un CDK projet - Resolver

Cet exemple utilisera deux résolveurs : l'un pour interroger la table et l'autre pour y ajouter des éléments. Puisque nous utilisons des résolveurs de pipeline, nous devrons déclarer deux résolveurs de pipeline avec une fonction dans chacun. Dans la requête, nous allons ajouter le code suivant :

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 }); } }

Dans cet extrait, nous avons ajouté un résolveur de pipeline appelé auquel est func-add-post attachée pipeline-resolver-create-posts une fonction appelée. Il s'agit du code qui sera ajouté Posts au tableau. L'autre résolveur de pipeline a été appelé pipeline-resolver-get-posts avec une fonction appelée func-get-post qui récupère les éléments Posts ajoutés à la table.

Nous allons le déployer pour l'ajouter au AWS AppSync service :

cdk deploy

Examinons la AWS AppSync console pour voir s'ils étaient attachés à notre GraphQL API :

GraphQL API schema showing mutation and query fields with Pipeline resolvers.

Cela semble correct. Dans le code, ces deux résolveurs étaient attachés au API GraphQL que nous avons créé (indiqué par la valeur props présente à api la fois dans les résolveurs et dans les fonctions). Dans GraphQLAPI, les champs auxquels nous avons attaché nos résolveurs étaient également spécifiés dans les accessoires (définis par les fieldname accessoires typename et de chaque résolveur).

Voyons si le contenu des résolveurs est correct, en commençant par : pipeline-resolver-get-posts

Code snippet showing request and response functions in a resolver, with an arrow pointing to them.

Les gestionnaires avant et après correspondent à la valeur de nos code accessoires. Nous pouvons également voir qu'une fonction est appeléeadd_posts_func_1, ce qui correspond au nom de la fonction que nous avons attachée dans le résolveur.

Regardons le contenu du code de cette fonction :

Function code showing request and response methods for a PutItem operation.

Cela correspond aux code accessoires de la add_posts_func_1 fonction. Notre requête a été chargée avec succès, alors vérifions-la :

Resolver code with request and response functions, and a get_posts_func_1 function listed below.

Ils correspondent également au code. Si nous examinons get_posts_func_1 :

Code snippet showing two exported functions: request returning 'Scan' operation and response returning items.

Tout semble être en place. Pour confirmer cela du point de vue des métadonnées, nous pouvons AWS CloudFormation réexaminer notre pile :

List of logical IDs for AWS resources including API, table, functions, and pipelines.

Maintenant, nous devons tester ce code en effectuant quelques requêtes.

Mise en œuvre d'un CDK projet - Demandes

Pour tester notre application dans la AWS AppSync console, nous avons effectué une requête et une mutation :

GraphQL code snippet showing a query to get post details and a mutation to create a post.

MyMutationcontient une createPost opération avec les arguments 1970-01-01T12:30:00.000Z etfirst post. Il renvoie le date et title que nous avons transmis ainsi que la id valeur générée automatiquement. L'exécution de la mutation donne le résultat suivant :

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

Si nous vérifions rapidement la table DynamoDB, nous pouvons voir notre entrée dans la table lorsque nous la scannons :

DynamoDB table entry showing id, date, and title fields for a single item.

De retour dans la AWS AppSync console, si nous exécutons la requête pour le récupérerPost, nous obtenons le résultat suivant :

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