AWS
AppSync
My first impression
AppSyncの感想
AppSync用語説明
AWS AppSync:
GraphQL API Managed service
Resolver:
AppSyncのデータ変換の処理を記述する箇所
defaultではVTLで記述する
AppSync採用時点
Managed Service なので便利
Subscriptionも
すぐに使える
DynamoDBとの組み合わせて簡単に始められる
serverless frameworkでも
サポートされている
実際に実装を始めたら
- Velocityナツい、js実装があるんだ
- テキストのテンプレートでロジックを記述する?
- まったく構造化も再利用もできない!
- テストどうするの?
VTLって何!
- queryの制約キツすぎる!
- テーブル設計が全然違う!
- 1テーブルに全て集約するの?
DynamoDB
ムズい
serverless frameworkの offline実行が便利
VTL (Velocity Template Language)
#set($expression = "")
#set($expressionNames = {})
#set($expressionValues = {})
#foreach($key in $ctx.args.input.keySet())
#if ($expression.length().equals(0))
#set($expression = "SET #$key = :$key")
#else
#set($expression = "${expression}, #$key = :$key")
#end
$util.qr($expressionNames.put("#$key", $key))
$util.qr($expressionValues.put(":$key", $ctx.args.input.get($key)))
#end
{
"version" : "2018-05-29",
"operation" : "UpdateItem",
"key" : {
"key": $util.dynamodb.toDynamoDBJson($ctx.args.key)
},
"update" : {
"expression": "$expression",
"expressionNames": $util.toJson($expressionNames),
"expressionValues": $util.dynamodb.toMapValuesJson($expressionValues)
}
}
VTL (Velocity Template Language)
## [Start] Determine request authentication mode **
#if( $util.isNullOrEmpty($authMode) && !$util.isNull($ctx.identity) && !$util.isNull($ctx.identity.sub) && !$util.isNull($ctx.identity.issuer) && !$util.isNull($ctx.identity.username) && !$util.isNull($ctx.identity.claims) && !$util.isNull($ctx.identity.sourceIp) && !$util.isNull($ctx.identity.defaultAuthStrategy) )
#set( $authMode = "userPools" )
#end
## [End] Determine request authentication mode **
## [Start] Check authMode and execute owner/group checks **
#if( $authMode == "userPools" )
## [Start] Owner Authorization Checks **
#set( $isOwnerAuthorized = false )
## Authorization rule: { allow: owner, ownerField: "owner", identityClaim: "cognito:username" } **
#set( $allowedOwners0 = $util.defaultIfNull($ctx.args.input.owner, null) )
#set( $identityValue = $util.defaultIfNull($ctx.identity.claims.get("username"), $util.defaultIfNull($ctx.identity.claims.get("cognito:username"), "___xamznone____")) )
#if( $util.isList($allowedOwners0) )
#foreach( $allowedOwner in $allowedOwners0 )
#if( $allowedOwner == $identityValue )
#set( $isOwnerAuthorized = true )
#end
#end
#end
#if( $util.isString($allowedOwners0) )
#if( $allowedOwners0 == $identityValue )
#set( $isOwnerAuthorized = true )
#end
#end
#if( $util.isNull($allowedOwners0) && (! $ctx.args.input.containsKey("owner")) )
$util.qr($ctx.args.input.put("owner", $identityValue))
#set( $isOwnerAuthorized = true )
#end
## [End] Owner Authorization Checks **
## [Start] Throw if unauthorized **
#if( !($isStaticGroupAuthorized == true || $isDynamicGroupAuthorized == true || $isOwnerAuthorized == true) )
$util.unauthorized()
#end
## [End] Throw if unauthorized **
#end
## [End] Check authMode and execute owner/group checks **
- DynamoDBは、いわゆるKey-Value Store
- そのため全てのデータに一意なKeyが必要
- Keyは以下の2種類のどちらか
- Partition Keyのみ
- Partition KeyとSort Keyのセット
- Partition Key: 格納するpartitionを決める
- Sort Key: partitionの中でのデータ順を決める
DynamoDB
- データの取得方法は以下の3つ
- GetItem:
- Keyを指定してデータを1つ取得
-
Query:
- Partition Keyを指定して複数のデータを取得、Sort Keyを使って範囲をフィルタすることも可能
- Scan:
- テーブルのデータを全件取得
- GetItem:
DynamoDB
一通りの実装が終わって
それならDynamoDB を使う必要もなかったね
Lambda
Resolverで
良くない?
- アクセス周りのテストが重要
- 実際にアクセスする必要があるので結合テストが必要
DynamoDBは癖強すぎ
serverless frameworkは 神
GraphQLのschemaでtimestampは何の型で定義していますか?
標準のScalarとしては以下の5つだけ
- Int: 32bit整数 (signed)
- Float: 倍精度浮動小数点数 (64bit)
- String: 任意の文字列 (UTF-8)
- Boolean: `true` or `false`
- ID: 一意の文字列
timestampとしてunix timeを採用する場合、
32bit signed-integerなのでミリ秒が含められない&2038年問題があります。
64bit の整数型があれば、ミリ秒もしくはマイクロ秒まで含められるのですが、AWS AppSyncではCustom Scalar typeを追加することができないため無理でした。
質問:GraphQLで
timestampの型は?
仕方ないので、今回は文字列で時刻をISO 8601フォーマットにしたものを使うことにしました。追加でサーバ側で受け取った文字列を、正規化してタイムゾーンをUTCに変換する処理を入れてます。
変換処理が必要なのはbackendがDynamoDBなので、Datetimeを保存する用の型が用意されていないため、ただの文字列として保存しないとならないのが原因ですかね?
他のプロジェクトではどうしているか、聞きたいです。
質問:GraphQLで
timestampの型は?
Thank You!
参考Link
AWS AppSync - My first impression
By Hiroki Horiuchi
AWS AppSync - My first impression
- 192