AppSync & GraphQL 入門
https://user-images.githubusercontent.com/7469495/105184322-9179a580-5b72-11eb-8f73-5bbe20a686ec.png
AppSync とは?
GraphQL というAPI仕様を用いて「柔軟なAPI」を提供するAWSのマネジメントサービス
ちなみに、従来の REST API 形式だと AWSは API Gateway を提供している
GraphQL とは?
Facebookが開発しているWeb APIのための規格
「クエリ言語」 と 「スキーマ言語」 からなる
REST API は、1URLに対し1つのAPIや情報を提供できるのに対し、
GraphQL は欲しいデータを以下のようなクエリとして発行すると、欲しいデータを欲しいObject形式で得ることができます
code: (javascript)
// リクエスト
query GetCurrentUser {
currentUser {
id
name
}
}
↓
code: (javascript)
// レスポンス
{
id: 'hoge',
name: 'yamada'
}
AppSyncの仕組み
https://user-images.githubusercontent.com/7469495/94530035-773f5300-0275-11eb-8e38-8d1435ec7b44.png
AppSyncは直接DynamoDBの値を取得・更新・削除することができます
従来のAPI Gatewayだと、AWS Lambda が間に必要でしたが、
AppSyncは Lambda レス でDynamoDBへのアクセスが可能です
代わりに、AppSync内のリゾルバーという領域にロジックを記述します
クエリ
実行されるGraphQlのこと
スキーマ
どの型の値をどこで使うかを定義する設計書
リゾルバー
関数のこと。ロジックを記述する。
リゾルバーは、リクエストマッピングテンプレート と レスポンスマッピングテンプレート で構成さる
リクエストマッピングテンプレート は、「変換」と「実行」のロジックが含まれている
リソース
データベースのこと。AppSync では AWS DynamoDB に自動的に接続される
AppSyncの料金
使用した分だけ課金されます
クエリとデータ変更操作
4.00USD ≒ 423.87 円 / クエリおよびデータ変更操作 100 万回あたり
リアルタイム更新
データが更新された際に、リアルタイムに更新する機能
2.00USD ≒ 211.94 円 / リアルタイムアップデート 100 万回
最初の12ヶ月の無料利用枠の対象でもあるようなので、登録後12ヶ月は一定回数は無料で使用できます
試してみる
実際に、AppSyncを用いてイベントを取得・登録する処理を実装してみます、とても簡単です
AppSync API を作成
AWS ログインして、AppSyncページへ移動し、「APIを作成」
サンプルプロジェクトから「イベントアプリ」を選んで「開始」
API 名は [yourname] App としてください
左メニューから「クエリ」ページに移動すると、GraphQL Explorer が表示されます
ここで、GraphQLを試すことが可能です
https://user-images.githubusercontent.com/7469495/94671324-b42b4880-034e-11eb-8cbf-d5b6b5870770.png
▶︎ボタンから、実行したいクエリを選択してみると、右側に結果が表示されます
https://user-images.githubusercontent.com/7469495/94671244-9b229780-034e-11eb-941a-3d4ee808f1c4.png
デフォルトで2つのクエリが用意されています
code:_
mutation CreateEvent {
createEvent(
name: "My First Event"
when: "Today"
where: "My House"
description: "Very first event"
) {
id
name
}
}
query ListEvents {
listEvents {
items {
id
name
}
}
}
1つめの mutation CreateEvent は、新たな Event のデータを作成するための mutation です
2つめの query ListEvents は、DBに登録されている Event のデータを取得するための query です
CreateEvent を何度か実行すると ListEvents の結果が変わることがわかります
GraphQLには3種類のクエリがある
table:table
名前 説明
query データ取得 (read)
mutation データ作成/更新/削除 (create / update / delete)
subscription リアルタイムイベントを受け取れる。内部的にはwebsocketが使われている
先ほどのサンプルでは query と mutation を使用しています
実際に Javascript で GraphQL を使ってみる
Axios を使って試してみます
URL と API KEY を AppSyncコンソールの設定ページから見つけて、セットしてみてください
上手くいけば、GraphQLのresultが、consoleに表示されます
code: (javascript)
const data = await axios.post(
API_URL,
{
query: `
// ここにqueryをかく
`
},
{
headers: {
// header に APIキーを渡す。 appSync設定画面から取得
"x-api-key": ""
}
}
);
request body にクエリを記述、request header に x-api-key として API KEY を持たせることで認証されます、とても簡単ですね
認証方法
appSyncでは、4つの認証方法が用意されています
table:table
名前 概要 ユースケース
API_KEY 今回使ったもの。最大 365 日間有効に設定可能で、該当日からさらに最大 365 日、既存の有効期限を延長可 パブリック API の公開が安全であるユースケース、または開発目的での使用が推奨
AWS_IAM IAMポリシーを紐づけて使用 IAMロールごとに、特定の機能のみに制限したい場合
OPENID_CONNECT OpenID Connect (OIDC) トークンを適用 OpenID Connectを使いたい場合(未調査)
AMAZON_COGNITO_USER_POOLS Amazon Cognito ユーザープールによって提供される OIDC トークンが使用されます Amazon Cognito ユーザープールによって提供されるOIDCトークンを使いたい場合(未調査)
基本的には、上2つ API_KEY と AWS_IAM を使うパターンが多いでしょう
データベースの中身を見てみる
左メニューから、 データソース を選択すると、DynamoDB へのリンクがあります
AppSync が自動生成してくれたテーブルが、ここに表示されています
https://user-images.githubusercontent.com/7469495/94674333-fb1b3d00-0352-11eb-9b56-5052469777db.png
APIを変更・追加してみる
createEvent に who という項目を追加してみる
AWSコンソールの左メニューから スキーマ を選択すると、定義されている Schema が表示されます
この中から、 Mutation の下にある createEvent を見つけ、引数に who を追加してみます
https://user-images.githubusercontent.com/7469495/97424426-0e222c80-1954-11eb-99c2-76ea52ab1f5d.png
右上から スキーマを保存 します
クエリ ページから、who に適当な値を追加して、実行してみます
https://user-images.githubusercontent.com/7469495/97554741-8b17d980-1a1a-11eb-883b-df4e39437046.png
これで、dynamoDBに who が追加されたか確認してみましょう
左メニューから データソース -> AppSyncEventTable のリソースを開きます
あれ、項目 who が追加されていると思いましたが、追加されていません😢
https://user-images.githubusercontent.com/7469495/97555381-6708c800-1a1b-11eb-8ecc-917b5e80cb44.png
理由は簡単です、 リゾルバー も変更する必要があります💡
リゾルバー とは、このページの冒頭で表示した図にあるように、ロジックを記述する領域です
リゾルバー の変更は、 スキーマ ページの右カラムから可能です
createEvent を見つけましょう⤵︎
https://user-images.githubusercontent.com/7469495/97555776-e4343d00-1a1b-11eb-955c-1aa84a2b914f.png
リクエストマッピングテンプレート を以下のようにして、 who を追記します
code: (json)
{
"version": "2017-02-28",
"operation": "PutItem",
"key": {
"id": { "S": "$util.autoId()"}
},
"attributeValues": {
"name": { "S": "$context.arguments.name" },
"where": { "S": "$context.arguments.where" },
"when": { "S": "$context.arguments.when" },
"who": { "S": "$context.arguments.who" },
"description": { "S": "$context.arguments.description" }
}
}
リゾルバーを保存して、実行すると、who 項目が追加されていることが確認できました🎉
https://user-images.githubusercontent.com/7469495/97556176-6fadce00-1a1c-11eb-95ee-f465e07f5ef8.png
今回は内部の挙動を理解するために、
ブラウザからAWSコンソールを通じてスキーマやリゾルバーの変更を行いましたが、
実際には AWS Cloudformation や Amplify Framework などを用いると良いそうです
まとめ
メリット
GraphQL は REST API に比べて欲しいデータを欲しい形式で得ることが可能
GraphQL により、画面や機能ごとに、個別にAPIを定義するコストが削減される
AppSync を使えばリソース(DynamoDB)との連携を楽に行うことができる
ちなみに、既存の REST API を AppSync でラップして、GraphQL を導入することも可能らしい(未調査)
デメリット
GraphQL, Appsync の学習コストがかかる
フロントエンドの都合の良いように、値を返す必要があるため、リゾルバーのロジックが複雑になる
効率的にデータを処理できないので、パフォーマンスが低下し、N+1問題が発生する
GraphQLは、ファイルの送信ができない
※ N+1問題・・・ループ処理の中で都度SQLを発行してしまい、大量のSQLが発行されてパフォーマンスが低下してしまう問題のこと
実際にAppSyncで実装してみたページ
dynamoDB に入っているニュースのデータを AppSync を使って表示しています
これから調べる
AWS_IAM を使った AppSync 認証方法。 Cognito を使うらしいです
参考
TJ.icon勉強会資料
TJ.iconツール