入門 1: AppSync で Hello, World!
まず AppSync で "Hello, World!" という文字列を返す単純な GraphQL API を作成し、サービスの利用法をみていきます
スキーマの作成
まずは GraphQL SDL(Schema Definition Language) を用いて GraphQL API のインターフェースを定義していきます。次のような単純な User データを返却する user クエリを定義します。
schema {
query: Query
}
type Query {
user(id: ID!): User
}
type User {
id: ID!
name: String!
}
データソース/リゾルバの作成
ことはじめとして、決まった値を返すようなリゾルバを定義します。
{ "id": 1, "name": "hoge" }
データソースは None タイプを選択したものを指定し、レスポンスマッピングテンプレートにて前述の定数値を返すように設定します。
クエリの実行
次のようなクエリを実行します。定数値を返すレスポンスマッピングテンプレートを設定しているので id を変えても常に同じ値が帰ります。name のみにすると、戻り値に id は含まれなくなります。
query {
user(id: 1) {
id
name
}
}
SAM テンプレート
CloudFormation テンプレートで以上のリソースを表現しておくとわかりやすいかもしれません。次のようになります。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
Hello AppSync
Resources:
GraphQLApi:
Type: AWS::AppSync::GraphQLApi
Properties:
Name: GraphQLHello
AuthenticationType: API_KEY
GraphQLSchema:
Type: AWS::AppSync::GraphQLSchema
Properties:
ApiId: !GetAtt GraphQLApi.ApiId
DefinitionS3Location: schema.graphql
GraphQLNoneDataSource:
Type: AWS::AppSync::DataSource
Properties:
Name: GraphQLNoneDataSource
ApiId: !GetAtt GraphQLApi.ApiId
Type: NONE
GraphQLResolver:
Type: AWS::AppSync::Resolver
Properties:
ApiId: !GetAtt GraphQLApi.ApiId
TypeName: Query
FieldName: user
DataSourceName: !GetAtt GraphQLNoneDataSource.Name
RequestMappingTemplate: '{"version": "2017-02-28", "payload": {}}'
ResponseMappingTemplate: '{"id":1, "name":"hoge"}'
GraphQLAPIKey:
Type: AWS::AppSync::ApiKey
Properties:
ApiId: !GetAtt GraphQLApi.ApiId
入門 2: 値を Lambda データソースから返却する
定数値をレスポンスマッピングテンプレートから返却するのではなく、Lambda 関数から返してみます。
データソースの作成
以下のような単純な Lambda 関数を作成し、これをデータソースとして指定します。
import json
def lambda_handler(event, context):
print(json.dumps(event, ensure_ascii=False))
return {
'id': event['id'],
'name': 'hogefuga'
}
リゾルバの作成
リゾルバのマッピングテンプレートを以下のように設定すると背後にある Lambda 関数をデータソースとして呼び出せます
# request
{ "version" : "2017-02-28", "operation": "Invoke", "payload": $util.toJson($context.args) }
# response
$util.toJson($context.result)
クエリの実行
以下のようなクエリを実行すると無事 Lambda から返却された id に対応するレスポンスが得られます(name は固定値ですが...)。
query {
user(id: 123) {
id
name
}
}
あわせて Lambda 関数の CloudWatch Logs をみると以下のようなイベントが渡っていることがわかります
{
'id': '123'
}
SAM テンプレート
Lambda 関数が絡んできたので SAM が生きます。テンプレートは以下のようなもの。AppSync から Lambda を実行する際の実行ロールがやや冗長なので、スマートにかけるようになると便利そうですね。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
Hello AppSync
Resources:
GraphQLApi:
Type: AWS::AppSync::GraphQLApi
Properties:
Name: GraphQLHello
AuthenticationType: API_KEY
GraphQLSchema:
Type: AWS::AppSync::GraphQLSchema
Properties:
ApiId: !GetAtt GraphQLApi.ApiId
DefinitionS3Location: schema.graphql
GraphQLDataSourceLambdaFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: get_user/
Handler: app.lambda_handler
Runtime: python3.8
AppSyncLambdaInvokeRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Principal:
Service: appsync.amazonaws.com
Action:
- sts:AssumeRole
Policies:
- PolicyName: AllowInvokeLambda
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: lambda:invokeFunction
Resource: !GetAtt GraphQLDataSourceLambdaFunction.Arn
GraphQLLambdaDataSource:
Type: AWS::AppSync::DataSource
Properties:
Name: GraphQLLambdaDataSource
ApiId: !GetAtt GraphQLApi.ApiId
Type: AWS_LAMBDA
LambdaConfig:
LambdaFunctionArn: !GetAtt GraphQLDataSourceLambdaFunction.Arn
ServiceRoleArn: !GetAtt AppSyncLambdaInvokeRole.Arn
GraphQLResolver:
Type: AWS::AppSync::Resolver
Properties:
ApiId: !GetAtt GraphQLApi.ApiId
TypeName: Query
FieldName: user
DataSourceName: !GetAtt GraphQLLambdaDataSource.Name
RequestMappingTemplate: '{ "version" : "2017-02-28", "operation": "Invoke", "payload": $util.toJson($context.args) }'
ResponseMappingTemplate: '$util.toJson($context.result)'
GraphQLAPIKey:
Type: AWS::AppSync::ApiKey
Properties:
ApiId: !GetAtt GraphQLApi.ApiId
入門 3: HTTP データソースの利用
- スキーマは以前と同様にデータソースを HTTP データソースに変更してみる
- 簡単のため JSONPlaceholder の Users API を叩く
データソースの作成
JSONPlaceholder のエンドポイント: https://jsonplaceholder.typicode.com を指定し、データソースを作成する
リゾルバの作成
リゾルバのマッピングテンプレートを以下のように設定すると背後にある HTTP エンドポイントをデータソースとして呼び出せる
# request
{"version":"2018-05-29","method":"GET","resourcePath":"/users/$ctx.args.id"}
# response
$context.result.body
クエリの実行
以下のようなクエリを実行する
query {
get(id: "3") {
id
name
}
}
すると以下のような結果が得られる
{
"data": {
"get": {
"id": "3",
"name": "Clementine Bauch"
}
}
}
SAM テンプレート
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
Hello AppSync
Resources:
GraphQLApi:
Type: AWS::AppSync::GraphQLApi
Properties:
Name: GraphQLHello
AuthenticationType: API_KEY
GraphQLSchema:
Type: AWS::AppSync::GraphQLSchema
Properties:
ApiId: !GetAtt GraphQLApi.ApiId
DefinitionS3Location: schema.graphql
GraphQLAPIKey:
Type: AWS::AppSync::ApiKey
Properties:
ApiId: !GetAtt GraphQLApi.ApiId
GraphQLHTTPDataSource:
Type: AWS::AppSync::DataSource
Properties:
Name: GraphQLHTTPDataSource
ApiId: !GetAtt GraphQLApi.ApiId
Type: HTTP
HttpConfig:
Endpoint: https://jsonplaceholder.typicode.com
GraphQLResolver:
Type: AWS::AppSync::Resolver
Properties:
ApiId: !GetAtt GraphQLApi.ApiId
TypeName: Query
FieldName: user
DataSourceName: !GetAtt GraphQLHTTPDataSource.Name
RequestMappingTemplate: '{"version":"2018-05-29","method":"GET","resourcePath":"/users/$ctx.args.id"}'
ResponseMappingTemplate: '$context.result.body'
Pinned Articles
About
ウェブ界隈でエンジニアとして労働活動に励んでいる @gomi_ningen 個人のブログです
Tags
JavaScript
PowerShell
kibana
elasticsearch
fluentd
nginx
イベント
五十嵐裕美
村川梨衣
logrotate
IoT
Scala
Java
C言語
iputils
ICMP
WUG
mastodon
Swift
AWS
Clock
Windows
アーキテクチャ
PoEAA
iOS
DeviceFarm
プログラミング言語
OS
StepFunctions
Lambda
Serverless
terraform
ポエム
RHEL
ネットワーク
GraphQL
CloudWatch
Linux
Coreutils
network
nc
telnet
LinuxKernel
fpinscala
ELB
IAM
AppSync
EFS
Gradle
english