2019.02.04
AWS Amplifyを使ってAppSyncを利用する場合、import { AmplifyService } from 'aws-amplify-angular';
で読み込んだAmplifyServiceをDIして以下のようにQuery・Mutation・Subscriptionを利用することができる。
// Query
this.amplifyService.api().graphql(graphqlOperation(queries.listPosts))
// Mutation
this.amplifyService.api().graphql(graphqlOperation(mutations.createPost, { input: {
content: `つぶやきテスト ${new Date()}`,
}}));
// Subscription
this.amplifyService.api().graphql(graphqlOperation(subscriptions.onCreatePost))
一方、AppSyncの強みである、オフラインでのアプリの利用とオンラインに復帰したときの同期を使うためにはAppSync SDKを利用する必要がある。
$ npm install --save aws-appsync graphql-tag
import { Component, OnInit } from '@angular/core';
import { AmplifyService } from 'aws-amplify-angular';
import { graphqlOperation } from 'aws-amplify';
import * as queries from '../../../../graphql/queries';
import * as mutations from '../../../../graphql/mutations';
import * as subscriptions from '../../../../graphql/subscriptions';
@Component({
selector: 'app-posts',
templateUrl: './posts.component.html',
styleUrls: ['./posts.component.scss']
})
export class PostsComponent implements OnInit {
posts = [];
constructor(
private amplifyService: AmplifyService,
) { }
ngOnInit() {
// サーバーからプッシュされる情報を受け取る
(<any>this.amplifyService.api().graphql(graphqlOperation(subscriptions.onCreatePost))).subscribe(data => {
this.posts.push(data.value.data.onCreatePost);
});
// 初回のデータ読み込みを行う
this.loadData();
}
async onAddPostClicked() {
this.amplifyService.api().graphql(graphqlOperation(mutations.createPost, { input: {
content: `つぶやきテスト ${new Date()}`,
}}));
}
private async loadData() {
const ret = await this.amplifyService.api().graphql(graphqlOperation(queries.listPosts));
this.posts = (<any>ret).data.listPosts.items;
}
}
import { Component, OnInit } from '@angular/core';
import { AmplifyService } from 'aws-amplify-angular';
import gql from 'graphql-tag';
import AWSAppSyncClient, { AUTH_TYPE } from 'aws-appsync';
import * as queries from '../../../../graphql/queries';
import * as mutations from '../../../../graphql/mutations';
import * as subscriptions from '../../../../graphql/subscriptions';
import amplify from '../../../../aws-exports';
@Component({
selector: 'app-posts',
templateUrl: './posts.component.html',
styleUrls: ['./posts.component.scss']
})
export class PostsComponent implements OnInit {
client;
posts = [];
constructor(
private amplifyService: AmplifyService,
) { }
async ngOnInit() {
this.client = new AWSAppSyncClient({
url: amplify.aws_appsync_graphqlEndpoint,
region: amplify.aws_appsync_region,
auth: {
type: AUTH_TYPE.AMAZON_COGNITO_USER_POOLS,
jwtToken: async () => (await this.amplifyService.auth().currentSession()).getIdToken().getJwtToken(),
}
});
this.client.subscribe({ query: gql(subscriptions.onCreatePost) }).subscribe(data => {
this.posts.push(data.data.onCreatePost);
}, error => {
console.warn(error);
});
// 初回のデータ読み込みを行う
this.loadData();
}
async onAddPostClicked() {
this.client.mutate({
mutation: gql(mutations.createPost),
variables: {
input: {
content: `つぶやきテスト ${new Date()}`,
}
},
});
}
private async loadData() {
this.client.query({
query: gql(queries.listPosts),
}).then(data => {
this.posts = data.data.listPosts.items;
});
}
}
AWSAppSyncClient
クラスのインスタンスはアプリケーション全体で一つで問題なさそうなので、CoreModuleにAppSyncServiceのようなサービスを作ってそこで持たせておくのが良いかもしれない。
this.client = new AWSAppSyncClient({
url: amplify.aws_appsync_graphqlEndpoint,
region: amplify.aws_appsync_region,
auth: {
type: AUTH_TYPE.AMAZON_COGNITO_USER_POOLS,
jwtToken: async () => (await this.amplifyService.auth().currentSession()).getIdToken().getJwtToken(),
}
});
url
には、AWS Amplifyが生成するaws-exports.js
のaws_appsync_graphqlEndpoint
の内容を指定する。
region
には、AWS Amplifyが生成するaws-exports.js
のaws_appsync_region
の内容を指定する。
また、AppSyncの認証モードをAMAZON_COGNITO_USER_POOLS
にした場合は必ずjwtToken
が必要になる。
認証モードがAMAZON_COGNITO_USER_POOLS
の場合は、ログインしていないユーザーはどのQuery・Mutation・Subscriptionも利用できない。未ログインユーザーに対してAPIの利用を許可するには、そもそもAppSyncの認証モードをIAMにする必要がある。
では、AMAZONCOGNITOUSER_POOLSモードはなんのためにあるのか?という疑問が湧いてくるが、このモードはサクッとアプリケーションのAPIを構築するときに使うものだそう。
ユーザーのアクセス制限も、Amazon Cognitoのユーザーグループに応じてQuery・Mutation・Subscriptionを許可・拒否するくらいしかできない。
細かいアクセス制御をしたい場合はAppSyncの認証モードをIAMにする。