* この記事では公式な方法ではなくハックで拡張する方法を共有しています。
AWS Amplifyではフレームワークの思想により、AppSync(GraphQL)APIを同一プロジェクトに1つしか作成できません。それだけでなく、Amplifyパッケージを利用した場合、アプリ側に設定できるGraphQLエンドポイントも1つしか設定できません。
長らくこの制限のせいで自由にマイクロサービスを設計することが困難でしたが、今回AWS SDKの内部構造を解析し簡単に外部のAppSyncをプロジェクトに混ぜ込む方法を見つけたので共有します。
やり方
この方法であればプロジェクトを複雑にすることなく、幾つでもAppSyncを取り込めます。
import {GraphQLAPIClass} from '@aws-amplify/api-graphql';
import {listPrices} from './graphql/queries.js';
import mainConfig from '@/aws-exports.js';
// インスタンス化する必要があります。
const GraphQLAPI = new GraphQLAPIClass();
// 環境設定 - configre()はAmplify.configre()と共通の関数です。
// 1. Cognito認証等が共通の場合は一旦メインのaws-exports.jsを取り込みます。
GraphQLAPI.configure(mainConfig);
// 2. 内部的にはObject.assign()するだけなので、第二のAppSync情報で上書きします。
GraphQLAPI.configure({
aws_appsync_graphqlEndpoint: process.env.OTHER_APPSYNC_ENDPOINTT,
aws_appsync_region: 'ap-northeast-1',
aws_appsync_authenticationType: 'AMAZON_COGNITO_USER_POOLS',
});
// 通常と同じ方法で接続できます。
const response = await GraphQLAPI.graphql({
query: listPrices,
variables: {crawlId, limit, nextToken},
});
注意点
GraphQLAPIClass
import {GraphQLAPIClass} from '@aws-amplify/api-graphql';
なぜ APIClass ではなく更に下の GraphQLAPIClass を使うかについては、サイズ的な問題で APIClass に @deprecated がマークされているためです。静的解析できるエディタであれば、 APIClass となり「非推奨」の表示が出てきます。
どちらにせよ、メインのAmplifyとは別設定のインスタンスを作ります。
configure()
const GraphQLAPI = new GraphQLAPIClass();
この部分ですが、コンストラクタに config を渡しても完全な設定ができませんでした。
一度空でインスタンス化してからconfigure()で設定する必要があります。
DataStore
こちらは未検証ですが、構造的に共通の方法でIndexedDBに複数のAppSyncプロジェクトが混ざると不具合が起きる可能性が高いと思います。 この設定だけで複数AppSyncのDataStoreは利用しない方が良いでしょう。
なんでそこまでして分けたいの?
マイクロサービス
単純にアプリ側というのは複数のマイクロサービスを複合して制作することが多いため、単一AppsSyncの制限というのはかなりハードルが高いです。GraphQLスキーマにHTTPやLambdaのプロキシを定義することも可能ですが、それは二重定義になり管理が大変になりますし、そもそも上手く出来ないから断続的にではありますが数年かけて試行錯誤していました。
amplify push が激遅くなる
まあ20個もスキーマ定義すると馬鹿みたいにデプロイに時間がかかるようになります。
これが無く、さらにスキーマ定義ファイルを構造的に分割できるなら何も考えず試行錯誤もしなかったかもしれないですね。