1. 開始方法
下記の方法で、アプリを簡単に作成できます。この場合、DynamoDBのテーブルが自動で生成されます。
- ウィザードで作成
- モデル名を好きに決める。モデルテーブル設定で作成するDynamoDBのテーブル名やプライマリキーを設定できる。
- APIの名前を決める
2. スキーマとリゾルバ―
スキーマ画面では以下のような構成になっています。Schemaではスキーマの定義が書いてあります。右側にはレゾルバーの定義が書いてあります。
以下のようなスキーマがデフォルトで作成されます。
input CreateMyModelTypeInput {
title: String
}
input DeleteMyModelTypeInput {
id: ID!
}
type Mutation {
createMyModelType(input: CreateMyModelTypeInput!): MyModelType
updateMyModelType(input: UpdateMyModelTypeInput!): MyModelType
deleteMyModelType(input: DeleteMyModelTypeInput!): MyModelType
}
type MyModelType {
id: ID!
title: String
}
type MyModelTypeConnection {
items: [MyModelType]
nextToken: String
}
type Query {
getMyModelType(id: ID!): MyModelType
listMyModelTypes(filter: TableMyModelTypeFilterInput, limit: Int, nextToken: String): MyModelTypeConnection
}
type Subscription {
onCreateMyModelType(id: ID, title: String): MyModelType
@aws_subscribe(mutations: ["createMyModelType"])
onUpdateMyModelType(id: ID, title: String): MyModelType
@aws_subscribe(mutations: ["updateMyModelType"])
onDeleteMyModelType(id: ID, title: String): MyModelType
@aws_subscribe(mutations: ["deleteMyModelType"])
}
input TableBooleanFilterInput {
ne: Boolean
eq: Boolean
}
input TableFloatFilterInput {
ne: Float
eq: Float
le: Float
lt: Float
ge: Float
gt: Float
contains: Float
notContains: Float
between: [Float]
}
input TableIDFilterInput {
ne: ID
eq: ID
le: ID
lt: ID
ge: ID
gt: ID
contains: ID
notContains: ID
between: [ID]
beginsWith: ID
}
input TableIntFilterInput {
ne: Int
eq: Int
le: Int
lt: Int
ge: Int
gt: Int
contains: Int
notContains: Int
between: [Int]
}
input TableMyModelTypeFilterInput {
id: TableIDFilterInput
title: TableStringFilterInput
}
input TableStringFilterInput {
ne: String
eq: String
le: String
lt: String
ge: String
gt: String
contains: String
notContains: String
between: [String]
beginsWith: String
}
input UpdateMyModelTypeInput {
id: ID!
title: String
}
順に内容を見ていきます。
2.1 型
基本的な型としては以下のものがあります。
名前 | 意味 |
---|---|
String | 文字列 |
Int | 整数型 |
Float | 整数型 |
Boolean | 論理型 |
ID | ID型 |
他にもリスト型なら[]で囲めば定義でき、オブジェクト型もtypeにより定義可能です。例えば、以下なら、MyModelTypeというオブジェクト型が定義されています。そして、MyModelTYpeConnectionのitemsでは、MyModelTypのリストが定義されています。
type MyModelType {
id: ID!
title: String
}
type MyModelTypeConnection {
items: [MyModelType]
nextToken: String
}
ここで出てくる「!」ですが、必ずあるという意味を示します。例えば、MyModelTypeなら必ずidを含みます。
2.2 ルートクエリ型
schemaを使用して、ルートクエリ型を定義できます(AWSコンソール側では表示されないが、schema.graphqlをエクスポートすると記述あり)。
schema {
query: Query
mutation: Mutation
subscription: Subscription
}
上記より、ルートクエリとして、Query、Mutation、Subscriptionがあることが分かります。それぞれ、検索、変更、更新時動作程度に理解しておくといいと思います。順にみていきます。
2.2.1 Query(検索)
Query部分の値を指定すると、その値を取得できます。例えば、以下ならgetMyModelTypeによりMyModelType型の値を得ることができます。また、listMyModelTypesによりMyModelTypeConnectionを得ることができます。
type Query {
getMyModelType(id: ID!): MyModelType
listMyModelTypes(filter: TableMyModelTypeFilterInput, limit: Int, nextToken: String): MyModelTypeConnection
}
形式としては「名前(引数): 戻り値」となります。戻り値のオブジェクト型はtype型で定義されており、引数のオブジェクト型はinput形で定義します。例えば、TableMyModelTypeFilterInputは以下のようになり、idとtitleを指定できることがわかります。
input TableMyModelTypeFilterInput {
id: TableIDFilterInput
title: TableStringFilterInput
}
getMyModelTypeやlistMyModelTypesの引数と戻り値はわかるけど動作はよくわかりません。動作を定義する部分はResolverと呼ばれる部分で行います。ResolverはSchemaウィンドウの右にあるResolversウィンドウのgetMyModelTypeの右側にリンクがあるのでそれをクリックするとみることができます。リゾルバにはリクエストマッピングテンプレートとレスポンスマッピングテンプレートがあります。リクエストマッピングテンプレートでは以下のようになっています。
{
"version": "2017-02-28",
"operation": "GetItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($ctx.args.id),
},
}
これは、DynamoDBからGetItemで値を取得するリクエストを出すという意味になります。$ctx.argsは、getMyModelTypeの引数を意味します。引数にidしかないので、idを取得できます。$utilは便利な関数が入っています。
レスポンスマッピングテンプレートは以下の通りです。
$util.toJson($context.result)
GetItemした結果をJSON形式で返すという意味になります。以上のことから、getMyModelTypeにより、DynamoDBにGetItem命令により値をとってくるという動作をしていることが分かります。
2.2.2 Mutation(変更)
データベースを更新する際はMutationを使用します。以下のように定義されています。
type Mutation {
createMyModelType(input: CreateMyModelTypeInput!): MyModelType
deleteMyModelType(input: DeleteMyModelTypeInput!): MyModelType
updateMyModelType(input: UpdateMyModelTypeInput!): MyModelType
}
リゾルバ―部分では、DynamoDBでのPutItem、DeleteItem、UpdateItemが使用されています。
2.2.3 Subscription (購読)
SubscriptionではMutationがあったらアプリに伝えることができます。以下のように定義されています。
type Subscription {
onCreateMyModelType(id: ID, title: String): MyModelType @aws_subscribe(mutations : ["createMyModelType"])
onDeleteMyModelType(id: ID, title: String): MyModelType @aws_subscribe(mutations : ["deleteMyModelType"])
onUpdateMyModelType(id: ID, title: String): MyModelType @aws_subscribe(mutations : ["updateMyModelType"])
}
@aws_subscribe部分をつけると、どのmutationが実行されたらトリガーを引くかを指定することができます。どれも更新のあったMyModelTypeが返ってくることが分かります。リゾルバ―はありません。
3. クエリ
定義したスキーマを使用する際にクエリを使用します。クエリはExpolorerで簡単に作成できます。真ん中のウィンドウに定義されたクエリが表示されます。右側は実行後のログが表示されます。
3.1 Mutation
下記の命令をするとmutationのcreateMyModelTypeが実行されます。idとtitleを返します。
mutation createMyModelType($createmymodeltypeinput: CreateMyModelTypeInput!) {
createMyModelType(input: $createmymodeltypeinput) {
id
title
}
}
引数にCreateMyModelTypeInputを指定します。$createmymodeltypeinputに下ウィンドウのクエリ変数で定義したものが入ります。この場合は、「Hello, world!」です。再生ボタンから実行すると、値がデータベースに登録されます。
3.2 Query
初期にlistMyModelTypesというクエリが定義されています。これを実行すると、queryで定義したlistMyModelTypesが実行されます。引数はないので、データベースの値をすべてリストでとってくることになります。itemsに値が格納されます。実行すると先ほど作成した項目が取得されます。
query listMyModelTypes {
listMyModelTypes {
items {
id
title
}
}
}
4. Cognitoとの連携
4.1 設定
設定を選択し、デフォルト認証モードのAPIレベルをAmazon Cognitoユーザープールを指定します。そして、AWSリージョンとユーザープールを選択します。これで保存すると、Cognitoでの認証ができるようになります。
デフォルトのアクションは、初期でのアクセスをどうするかをしています。ALLOWの場合は、Cognitoユーザーなら初期からAPIをすべて使用できます。DENYにすると、「@aws_auth」による制御をスキーマにつけて許可しないとAPIを使用することができません。
4.2 リゾルバーでCognitoの情報を使う
Cognitoのusernameを使ってDynamoDBを操作したいケースは多いと思います。その場合は、「$context.identity」を使用します。例えば以下のように「createMyModelType」を変更すると、DynamoDBにidがusernameで登録されるようになります。
{
"version": "2017-02-28",
"operation": "PutItem",
"key": {
"id": $util.dynamodb.toDynamoDBJson($context.identity.username),
},
"attributeValues": $util.dynamodb.toMapValuesJson($ctx.args.input),
"condition": {
"expression": "attribute_not_exists(#id)",
"expressionNames": {
"#id": "id",
},
},
}
ユーザーのクレームを取りたい場合は「$context.identity.claims.get(“email”)」のようにします。email部分はとりたい値に依存して変えてください。