💽
AWS AmplifyのAPI入力バリデーション実現方法
この記事は何
- Amplify CLIを使うと簡単にAppSync+DynamoDBを使ったGraphQL APIを作成可能です。(公式リンク)
- 開発者が下記のようなschemaを定義することで、Amplify CLIはDynamoDBのテーブルや、AppSyncのリゾルバ(query, mutation, subscribe用)を生成してくれます。
schemaの例
type Blog @model {
id: ID!
name: String!
posts: [Post] @connection(name: "BlogPosts")
}
type Post @model {
id: ID!
title: String!
blog: Blog @connection(name: "BlogPosts")
comments: [Comment] @connection(name: "PostComments")
}
type Comment @model {
id: ID!
content: String
post: Post @connection(name: "PostComments")
}
- 上記の例中にある
@model
や@connection
をディレクティブと呼び、これによってschemaからどのようにリゾルバを生成するかコントロールしています(ざっくり)。 - Issueも出て議論されているのでそのうち実装されそうですが、現状は入力に対するバリデーションを定義するディレクティブはありません。こちらの開発をする時に、ユーザ入力をDynamoDBに書き込む必要があったのですが、「あれ、バリデーションが無いとか怖すぎない…?」となりました。
- したがって、一度Amplify CLIが生成した
.vtl
ファイルを直接編集する必要があります[1]。その方法を備忘録として残します。
前提
- Amplify CLI 3.3.26
問題設定
次のようなschemaを定義した時に、idの長さに制限を設けたいとします。(例えばブランクは禁止かつ50文字未満とする)
schema.graphql
type Fav @model
@key(fields:["owner", "id"])
owner: ID!
id: ID!
}
手順
(amplify apiの追加は事前に済んでいるものとして…)
-
amplify push
を実行してリゾルバを生成する - 生成されたリゾルバのうち、バリデーションの追加が必要な処理用のリゾルバ(例えばCreateFavなど)をコピーして指定場所に保存する。
リゾルバの生成場所
ProjectRoot
|- amplify
|- backend
|- api
|- yourApiName
|- build
| |- resolvers --- ※ここに生成される
|
|- resolvers -------- ※ここにコピーして保存する
- コピーしたファイルを次のように編集する。正直VTLの記述方法が分からないので、挿入場所は手探り感がありますが、自動生成されたコメントを手がかりに、primary keyの付与前にバリデーションを実施するように、次のような位置に挿入しています。
(略)
+ ## Custom for input validation
+ #if($util.isNullOrBlank($ctx.args.input.id))
+ $util.appendError("id must exist", "id", null, $ctx.args.input.id)
+ #end
+ #if($ctx.args.input.id.length() > 50))
+ $util.appendError("The request would not be proper", "id", null, ctx.args.input.id)
+ #end
+ #if($ctx.outErrors.size() > 0)
+ #return($ctx.outErrors)
+ #end
## [Start] Set the primary @key. **
#set( $modelObjectKey = {
"owner": $util.dynamodb.toDynamoDB($ctx.args.input.owner),
"id": $util.dynamodb.toDynamoDB($ctx.args.input.id)
} )
## [End] Set the primary @key. **
## [Start] Prepare DynamoDB PutItem Request. **
(略)
- ファイルを上書き保存した後、再度
amplify push
する。
おわりに
お疲れさまでした。設定方法は以上となります。念のためAppSyncコンソールなどで試しにクエリを行い、狙い通りにバリデーションが機能しているか確認してみて下さい。
-
カスタムディレクティブを作る方法もあり、Amplifyのドキュメントで解説されていますが、私はそこに着手するガッツはありませんでした…。 ↩︎
Discussion