での AWS AppSync APIの使用 AWS CDK - AWS AppSync

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

での AWS AppSync APIの使用 AWS CDK

ヒント

を使用する前にCDK、 CDKの公式ドキュメントと AWS AppSyncのCDKリファレンスを確認することをお勧めします。

また、 AWS CLINPMのインストールがシステムで機能していることを確認することをお勧めします。

このセクションでは、DynamoDB テーブルから項目を追加およびフェッチできるシンプルなCDKアプリケーションを作成します。これは、スキーマの設計 、データソースのアタッチ https://docs.aws.amazon.com/appsync/latest/devguide/attaching-a-data-source.htmlリゾルバーの設定 (JavaScript) セクションのコードの一部を使用したクイックスタートの例です。

CDK プロジェクトのセットアップ

警告

環境によっては、これらの手順が完全に正確ではない場合があります。システムに必要なユーティリティがインストールされ、 AWS サービスとインターフェイスする方法、適切な設定が整っていると仮定しています。

最初のステップは、 のインストールです AWS CDK。ではCLI、次のコマンドを入力できます。

npm install -g aws-cdk

次に、プロジェクトディレクトリを作成して、そこに移動する必要があります。ディレクトリを作成して、そこに移動するコマンドのセット例は次のとおりです。

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

次に、アプリを作成する必要があります。当社のサービスは主に を使用します TypeScript。プロジェクトディレクトリで次のコマンドを入力します。

cdk init app --language typescript

これを行うと、初期化ファイルとともにCDKアプリケーションがインストールされます。

Terminal output showing Git repository initialization and npm install completion.

プロジェクト構造は次のようになります。

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

いくつかの重要なディレクトリがあるのがわかります。

  • bin: 最初の bin ファイルによってアプリが作成されます。このガイドではこれについては触れません。

  • lib: lib ディレクトリにはスタックファイルが含まれます。スタックファイルは個々の実行単位と考えることができます。コンストラクトはスタックファイル内にあります。基本的に、これらは、アプリがデプロイされた AWS CloudFormation ときに にスピンアップされるサービスのリソースです。ほとんどのコーディングはここで行われます。

  • node_modules: このディレクトリは によって作成NPMされ、 npm コマンドを使用してインストールしたすべてのパッケージ依存関係が含まれています。

最初のスタックファイルには次のような内容が含まれる場合があります。

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

これはアプリでスタックを作成するためのボイラープレートコードです。この例では、コードのほとんどはこのクラスのスコープ内にあります。

スタックファイルがアプリ内にあることを確認し、アプリのディレクトリからターミナルで以下のコマンドを実行します。

cdk ls

スタックが一覧表示されます。表示されない場合は、手順をもう一度実行するか、公式ドキュメントでヘルプを確認する必要があります。

デプロイする前にコードの変更をビルドする場合は、ターミナルでいつでも以下のコマンドを実行できます。

npm run build

また、デプロイ前に変更を確認します。

cdk diff

スタックファイルにコードを追加する前に、ブートストラップを実行します。ブートストラップを使用すると、アプリケーションのデプロイCDK前に のリソースをプロビジョニングできます。このプロセスの詳細については、こちらを参照してください。ブートストラップを作成するには、以下のコマンドを実行します。

cdk bootstrap aws://ACCOUNT-NUMBER/REGION
ヒント

このステップでは、アカウントに複数のIAMアクセス許可が必要です。これらのアクセス許可がないと、ブートストラップは拒否されます。拒否された場合、ブートストラップが生成する S3 バケットなど、ブートストラップが原因で発生した不完全なリソースを削除しなければならない場合があります。

ブートストラップは複数のリソースを起動します。最終メッセージは次のようになります。

Terminal output showing successful bootstrapping of an AWS environment.

これは各リージョンのアカウントごとに 1 回行われるため、頻繁に行う必要はありません。ブートストラップの主なリソースは、 AWS CloudFormation スタックと Amazon S3 バケットです。

Amazon S3 バケットは、デプロイの実行に必要なアクセス許可を付与するファイルとIAMロールを保存するために使用されます。必要なリソースは、ブートストラップスタックと呼ばれる AWS CloudFormation スタックで定義され、通常は と呼ばれますCDKToolkit。他の AWS CloudFormation スタックと同様に、デプロイされると AWS CloudFormation コンソールに表示されます。

CDKToolkit stack with CREATE_COMPLETE status in AWS CloudFormation console.

バケットについても同じことが言えます。

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

スタックファイルで必要なサービスをインポートするには、以下のコマンドを使用できます。

npm install aws-cdk-lib # V2 command
ヒント

V2 に問題がある場合は、V1 コマンドを使用して個々のライブラリをインストールできます。

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

V1 は廃止されたため、これはお勧めしません。

CDK プロジェクトの実装 - スキーマ

これで、コードの実装を開始できます。まず、スキーマを作成する必要があります。アプリ内で .graphql ファイルを作成するだけです。

mkdir schema touch schema.graphql

この例では、schema.graphql を含む schema という最上位ディレクトリを含めました。

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

スキーマの中に、簡単な例を含めてみましょう。

input CreatePostInput { title: String content: String } type Post { id: ID! title: String content: String } type Mutation { createPost(input: CreatePostInput!): Post } type Query { getPost: [Post] }

スタックファイルに戻って、次の import ディレクティブが定義されていることを確認する必要があります。

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

クラス内で、GraphQL を作成するためのコードを追加APIし、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'), }); } }

また、GraphQL 、APIキーURL、リージョンを出力するコードも追加します。

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

この時点で、アプリを再度デプロイします。

cdk deploy

こちらがその結果です。

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

この例では成功したようですが、 AWS AppSync コンソールを確認して確認しましょう。

GraphQL interface showing successful API request with response data displayed.

API が作成されたようです。次に、 にアタッチされているスキーマを確認しますAPI。

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

これはスキーマコードと一致しているようなので、成功です。メタデータの観点からこれを確認するもう 1 つの方法は、 AWS CloudFormation スタックを調べることです。

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

CDK アプリケーションをデプロイすると、ブートストラップなどのリソースがスピンアップ AWS CloudFormation されます。アプリ内の各スタックは、 AWS CloudFormation スタックと 1:1 でマッピングされます。スタックコードに戻ると、スタック名はクラス名 ExampleCdkAppStack から取得されています。作成したリソースは、GraphQL APIコンストラクトの命名規則とも一致します。

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

CDK プロジェクトの実装 - データソース

次に、データソースを追加する必要があります。この例では DynamoDB テーブルを使用します。stack クラス内に、新しいテーブルを作成するコードをいくつか追加します。

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

この時点で、もう一度デプロイしてみましょう。

cdk deploy

DynamoDB コンソールで新しいテーブルを確認する必要があります。

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

スタック名は正しく、テーブル名はコードと一致しています。 AWS CloudFormation スタックを再度チェックすると、新しいテーブルが表示されます。

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

CDK プロジェクトの実装 - リゾルバー

この例では、2 つのリゾルバーを使用します。1 つはテーブルのクエリ用、もう 1 つはテーブルへの追加用です。パイプラインリゾルバーを使用しているため、それぞれ 1 つの関数を持つ 2 つのパイプラインリゾルバーを宣言する必要があります。このクエリでは、次のコードを追加します。

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

このスニペットでは、func-add-post という関数がアタッチされた pipeline-resolver-create-posts というパイプラインリゾルバーを追加しました。これがテーブルに Posts を追加するコードです。もう一方のパイプラインリゾルバーは pipeline-resolver-get-posts と呼ばれ、テーブルに追加された Posts を取得する func-get-post と呼ばれる関数を持ちます。

これをデプロイして AWS AppSync サービスに追加します。

cdk deploy

AWS AppSync コンソールをチェックして、GraphQL にアタッチされているかどうかを確認しますAPI。

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

正しく接続されているようです。コードでは、これらのリゾルバーの両方が、API作成した GraphQL にアタッチされました (リゾルバーと関数の両方に存在する props api 値で示されます)。GraphQL ではAPI、リゾルバーをアタッチしたフィールドも props (各リゾルバーの typenameおよび fieldname props で定義) で指定されました。

リゾルバーのコンテンツが正しいかどうか、pipeline-resolver-get-posts を手始めに見てみましょう。

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

before ハンドラーと after ハンドラーは code props の値と一致しています。また、add_posts_func_1 という関数がリゾルバーにアタッチした関数の名前と一致していることもわかります。

この関数のコードコンテンツを見てみましょう。

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

これは add_posts_func_1 関数の code props と一致します。クエリが正常にアップロードされたので、クエリを確認してみましょう。

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

これらもコードと一致しています。get_posts_func_1 を見てみましょう。

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

すべてが正常に見えます。メタデータの観点からこれを確認するには、スタックをもう一度 AWS CloudFormation にチェックインします。

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

次に、いくつかのリクエストを実行して、このコードをテストする必要があります。

CDK プロジェクトの実装 - リクエスト

AWS AppSync コンソールでアプリケーションをテストするために、1 つのクエリと 1 つのミューテーションを行いました。

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

MyMutation には、引数 1970-01-01T12:30:00.000Zfirst post を含む createPost オペレーションが含まれています。渡した date および title とともに、自動生成された id 値が返されます。ミューテーションを実行すると、以下の結果が得られます。

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

DynamoDB テーブルをすばやく確認すると、スキャンしたときにテーブルにエントリが表示されます。

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

AWS AppSync コンソールに戻り、クエリを実行してこの を取得するとPost、次の結果が得られます。

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