やりたいこと
AWS Amplify を使ってアプリ開発を行っていて、後でバッチ処理などで Lambda や EC2 からも Mutation を発行したいという想定です。
直接 DynamoDB をいじってしまうのもありですが、 AppSync で定義したスキーマから外れたデータを投入できてしまったり、 Subscription が発行されなかったりするので AppSync 経由でデータを更新します。
Lambda 関数の詳しい実装については以下の記事が参考になるので割愛します。
AWS Lambda から AppSync の API を ぶん殴る
LambdaからAppSyncをIAM認証で使う
やり方
複数認証タイプのサポートによって、ユーザープール認証と IAM 認証を同時に使うことができるようになりました。
AppSync のスキーマ上では @aws_cognito_user_pools
や @aws_iam
のアノテーションを付与することで認証方法を制御可能です。 (公式ドキュメント)
しかし、同じように Amplify のスキーマを書いてみてもエラーになりました。 Apmlify では @auth
ディレクティブを使います。
# 通常の model
type Todo @model {
id: ID!
name: String!
description: String
}
# IAM 認証からもアクセス可能な model
type Todo
@model
@auth(rules: [{ allow: private }, { allow: private, provider: iam }]) {
id: ID!
name: String!
description: String
}
今までユーザープール認証を使っていて、初めて IAM 認証を追加した後に amplify push
をしようとすると、 iam
プロバイダーがないというエラーにより失敗します。
@auth directive with 'iam' provider found, but the project has no IAM authentication provider configured.
この場合は amplify update api
コマンドによって IAM 認証を追加します。
$ amplify update api
? Please select from one of the below mentioned services
> GraphQL
? Choose the default authorization type for the API
> Amazon Cognito User Pool
? Do you want to configure advanced settings for the GraphQL API
> Yes, I want to make some additional changes.
? Choose the additional authorization types you want to configure for the API
[x] IAM
GraphQL schema compiled successfully.
生成されたコード
Todo
や関連する Query, Mutation, Subscription に @aws_iam
@aws_cognito_user_pools
が付与されていることがわかります。通常の AppSync で設定する場合と同じようになっていますね。
type Todo @aws_iam @aws_cognito_user_pools {
id: ID!
name: String!
description: String
}
type ModelTodoConnection @aws_iam @aws_cognito_user_pools {
items: [Todo]
nextToken: String
}
type Query {
getTodo(id: ID!): Todo @aws_iam @aws_cognito_user_pools
listTodos(filter: ModelTodoFilterInput, limit: Int, nextToken: String): ModelTodoConnection @aws_iam @aws_cognito_user_pools
}
type Mutation {
createTodo(input: CreateTodoInput!): Todo @aws_iam @aws_cognito_user_pools
updateTodo(input: UpdateTodoInput!): Todo @aws_iam @aws_cognito_user_pools
deleteTodo(input: DeleteTodoInput!): Todo @aws_iam @aws_cognito_user_pools
}
type Subscription {
onCreateTodo: Todo @aws_subscribe(mutations: ["createTodo"]) @aws_iam @aws_cognito_user_pools
onUpdateTodo: Todo @aws_subscribe(mutations: ["updateTodo"]) @aws_iam @aws_cognito_user_pools
onDeleteTodo: Todo @aws_subscribe(mutations: ["deleteTodo"]) @aws_iam @aws_cognito_user_pools
}
所感
1年くらい Amplify を使っていますが結構な頻度で機能追加されていたりドキュメントが変わっていたりするので、まだまだ発展途上だなというように感じます
(今回も別のところでハマってしまって2時間くらいデプロイに失敗しました)
ソースコードや Issue を追ったり、場合によってはプルリクを出すくらいのつもりで付き合っていくのがいいと思います。