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 NPM
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 :
La structure de votre projet peut ressembler à ceci :
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 lanpm
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 :
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 :
Il en va de même pour le bucket :
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
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 :
Il semble que notre exemple soit réussi, mais vérifions la AWS AppSync console juste pour confirmer :
Il semblerait que le nôtre API ait été créé. Maintenant, nous allons vérifier le schéma joint au API :
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 :
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 :
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 :
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 :
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 :
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
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 :
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 :
Ils correspondent également au code. Si nous examinons get_posts_func_1
:
Tout semble être en place. Pour confirmer cela du point de vue des métadonnées, nous pouvons AWS CloudFormation réexaminer notre pile :
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 :
MyMutation
contient 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 :
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" } ] } }