なにこれ
AWSのGraphQLマネージドサービス「AppSync」はGUIで簡単に設定ができて便利ですが、 本格的に開発を進めていくとGUIポチポチでソースコードを管理するのはつらくなってきます。 Serverless Frameworkというツールとserverless-appsync-plugin(Serverless Frameworkのプラグイン)を使うと、AppSyncの設定をymlファイルで管理し、CLIでAWS上にデプロイできるので、GitHub等で構成管理が可能になります。 今回はAppSyncからDynamoDBのユーザー情報を1件取得する場合を例にしてAppSync + Serverless Frameworkの使い方をご紹介します。
1. Serverless Frameworkの設定
- Serverless Frameworkはnpmで提供されるCLIツールです。まずはnpmでインストールします。
npm i -g serverless
- クレデンシャルを設定します(事前にIAMでユーザを作成しておいてください)
serverless config credentials --provider aws --key AKIAIOSFODNN7EXAMPLE --secret wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
※詳細:Serverless Framework - AWS Lambda Guide - Credentials
2. プロジェクトのひな型作成
プロジェクトのひな型を作ります。 Serverless FrameworkでAppSync資産を扱えるように、serverless-appsync-pluginとaws-sdkをインストールします。
mkdir appsync-sample-with-serverless
cd appsync-sample-with-serverless
npm init -y
npm i serverless-appsync-plugin aws-sdk
3. 設定ファイル作成
プロジェクト直下にServerless Frameworkの設定ファイルserverless.yml
を作ります。
※ここではserverless.ymlの全量を示して、次のセクションでブロックごとに詳細を説明します。
# サービス名
service: appsync-sample-with-serverless
provider:
name: aws
# ステージ、デプロイ先を開発、運用などで分けたい場合はココを切り替えます
stage: production
# デプロイ先のリージョンです
region: ap-northeast-1
# AppSyncのプラグインを指定します
plugins:
- serverless-appsync-plugin
# プラグイン関連の設定はcustomで行います
custom:
# ここでAppSyncの設定を行います
appSync:
# エンドポイントの名前を指定します
name: appsync-serverless-sample
# AppSyncの認証方法を指定します
# ここではCognitoによる認証方法を指定しています
authenticationType: AMAZON_COGNITO_USER_POOLS
# Cogtnitoによる認証方法の場合、Cognito側の情報を指定する必要があります
userPoolConfig:
# Cognitoが存在するリージョンを指定します
# デフォルトだとproviderのregionで指定した値になります
awsRegion: ap-northeast-1
# CognitoのユーザープールのIDを指定します
userPoolId: ap-northeast-1_U0e7zFRLQ
# スキーマ定義で認証設定が記述されていない場合の挙動を指定します
# DENYを指定すると、認証されたいかなるユーザーも認可エラーに倒します
defaultAction: DENY
# AppSyncのスキーマ定義ファイルのパスを指定します
# デフォルトだとschema.graphqlです
schema: schema.graphql
# データソースを指定します(複数指定可能)
dataSources:
# データソースの型を指定します
# 以下が指定できます
# AMAZON_DYNAMODB ・・・DynamoDB
# AMAZON_ELASTICSEARCH ・・・Elasticsearch
# AWS_LAMBDA ・・・Lambda関数
- type: AMAZON_DYNAMODB
# データソース名を指定します
name: dynamo_user
# DynamoDBのテーブルの説明を指定します
description: 'ユーザー情報テーブル'
config:
# 参照するテーブル名を指定します
tableName: dynamo_user
# データソースのロールARNを指定します
serviceRoleArn: arn:aws:iam::999999999999:role/sample_role_arn
# データソースのリージョンを指定します
# デフォルトだとproviderのregionで指定した値になります
region: ap-northeast-1
# マッピングテンプレートのVTLファイルの格納先を指定します
# デフォルトはmapping-templatesです
mappingTemplatesLocation: mapping-templates
# リゾルバー定義を指定します
# ※ここではPipeline Resolverの例を示します
mappingTemplates:
# リゾルバーの方を指定します
- type: Query
# リゾルバーを紐づけるスキーマ中のフィールド名を指定します
field: user
# Pipeline Resolverを使い場合、以下を指定します
kind: PIPELINE
# リクエストマッピングテンプレートのファイルパスを指定します
# ファイルパスはmappingTemplatesLocationで指定したパスからの相対パスになります
request: 'start.vtl'
# レスポンスマッピングテンプレートのファイルパスを指定します
response: 'end.vtl'
# リゾルバーで使う関数を実行順に指定します
functions:
- GetUser
# 関数定義を指定します
functionConfigurations:
# ユーザー一覧取得
# 関数で扱うデータソース名を指定します
- dataSource: dynamo_user
# 関数名を指定します
name: 'GetUser'
# 関数のリクエストマッピングテンプレートのファイルパスを指定します
# ファイルパスはmappingTemplatesLocationで指定したパスからの相対パスになります
request: 'GetUser.req.vtl'
# 関数のレスポンスマッピングテンプレートのファイルパスを指定します
response: 'GetUser.res.vtl'
以下で、serverless.yml
に定義したプロパティがAWSコンソール上のどの項目に紐づくかを説明します。
AppSyncの基本設定
# ここでAppSyncの設定を行います
appSync:
# エンドポイントの名前を指定します
name: appsync-serverless-sample
# AppSyncの認証方法を指定します
# ここではCognitoによる認証方法を指定しています
authenticationType: AMAZON_COGNITO_USER_POOLS
# Cogtnitoによる認証方法の場合、Cognito側の情報を指定する必要があります
userPoolConfig:
# Cognitoが存在するリージョンを指定します
# デフォルトだとproviderのregionで指定した値になります
awsRegion: ap-northeast-1
# CognitoのユーザープールのIDを指定します
userPoolId: ap-northeast-1_U0e7zFRLQ
# スキーマ定義で認証設定が記述されていない場合の挙動を指定します
# DENYを指定すると、認証されたいかなるユーザーも認可エラーに倒します
defaultAction: DENY
AWSコンソールのAppSyncの画面で、エンドポイント一覧が表示されます。
serverless.yml
で定義したエンドポイント名はココで確認できます。
エンドポイントの画面を開きSettings
を確認するとuserPoolConfigなどの詳細が確認できます。
ほぼserverless.yml
のプロパティ名と一致しているので、なんとなく紐づけがわかると思います。
データソース定義
# データソースを指定します(複数指定可能)
dataSources:
# データソースの型を指定します
# 以下が指定できます
# AMAZON_DYNAMODB ・・・DynamoDB
# AMAZON_ELASTICSEARCH ・・・Elasticsearch
# AWS_LAMBDA ・・・Lambda関数
- type: AMAZON_DYNAMODB
# データソース名を指定します
name: dynamo_user
# DynamoDBのテーブルの説明を指定します
description: 'ユーザー情報テーブル'
config:
# 参照するテーブル名を指定します
tableName: dynamo_user
# データソースのロールARNを指定します
serviceRoleArn: arn:aws:iam::999999999999:role/sample_role_arn
# データソースのリージョンを指定します
# デフォルトだとproviderのregionで指定した値になります
region: ap-northeast-1
エンドポイントの画面を開きData Sources
を確認すると
データソースが一覧表示されるので、一覧から今回serverless.yml
に定義したデータソースを選択すると、以下のように詳細が確認できます。
リゾルバー定義
# リゾルバー定義を指定します
# ※ここではPipeline Resolverの例を示します
mappingTemplates:
# リゾルバーの方を指定します
- type: Query
# リゾルバーを紐づけるスキーマ中のフィールド名を指定します
field: user
# Pipeline Resolverを使い場合、以下を指定します
kind: PIPELINE
# リクエストマッピングテンプレートのファイルパスを指定します
# ファイルパスはmappingTemplatesLocationで指定したパスからの相対パスになります
request: 'start.vtl'
# レスポンスマッピングテンプレートのファイルパスを指定します
response: 'end.vtl'
# リゾルバーで使う関数を実行順に指定します
functions:
- GetUser
リゾルバー定義は、エンドポイントの画面を開きSchema
を確認します。
今回はuser
というフィールド名のクエリに対してリゾルバーを割り当てているので、右側のペインで以下のように確認できます。
上記画面のPipeline
のリンクを開くとリゾルバーの詳細が確認できます。
関数定義
# 関数定義を指定します
functionConfigurations:
# ユーザー一覧取得
# 関数で扱うデータソース名を指定します
- dataSource: dynamo_user
# 関数名を指定します
name: 'GetUser'
# 関数のリクエストマッピングテンプレートのファイルパスを指定します
# ファイルパスはmappingTemplatesLocationで指定したパスからの相対パスになります
request: 'GetUser.req.vtl'
# 関数のレスポンスマッピングテンプレートのファイルパスを指定します
response: 'GetUser.res.vtl'
関数定義は、エンドポイントの画面を開きFunctions
を確認します。
関数が一覧表示されるので、一覧から今回serverless.yml
に定義した関数を選択すると、以下のように詳細が確認できます。
設定ファイルの説明は以上です。次にリゾルバーとスキーマの定義について説明します。
4. リゾルバー作成
mapping-templates
フォルダを作成し、その中にリクエストマッピングテンプレートとレスポンスマッピングテンプレートを作成します。
PipelineResolver用のマッピングテンプレート
{}
PipelineResolver用のマッピングテンプレート
$util.toJson($ctx.result)
ユーザー1件取得用の関数ではDynamoDBのGetItemを呼び出します。
{
"version": "2018-05-29",
"operation": "GetItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($ctx.args.id),
}
}
取得情報をレスポンスにて返却します。
#if($ctx.error)
$util.error($ctx.error.message, $ctx.error.type)
#end
#set($res = { "user": $ctx.result })
$util.toJson($res)
5. スキーマ作成
ユーザー情報(ID、名前)を1件検索するだけのシンプルなスキーマ定義です。
serverless.yml
のschema
で指定した通り、プロジェクトルートにschema.graphql
ファイルを作成します。
type User {
id: ID!
name: String
}
type UserResponse {
user: User
}
input GetUserInput {
id: ID!
}
# ユーザー1件取得type Query { user(id: ID!): UserResponse}
6. AWSにデプロイ
以下コマンドを実行します。とても簡単にデプロイできます。
serverless deploy -v
まとめ
今回はAppSync + Serverless FrameworkによるAppSync資産の構成管理についてご紹介しました。 複数人開発においてGUI操作の場合、意図せず変更が加えられてデグレするリスクがあるので、Serverless Frameworkを使って構成管理するのが得策です。 またServerless Frameworkの利点はなんといっても1コマンドでAWSにデプロイという手軽さです。 AppSync資産だけでなく、Lambdaや他資産もServerless Frameworkで管理できるので、AWSでサーバーレスなアプリを開発するときは是非使ってみてください🍅