こんにちは!
最近は、AppSync/GraphQL での開発案件が非常に増えてきました。
GraphQL は、RestAPI のようなリソース志向の API設計に対し、データアクセス志向な API 設計を可能にします。つまり、フロントエンドの画面の振る舞いを起点にした API 設計/開発を行うことができます。
また、2018年にAws API GatewayがWebSocket APIに対応しました。
それまでは AppSync のメリットはサブスクリプション通信可能であることが挙げられていましたが、API Gateway が Web Socket に対応したことで、両者に明確に機能面で優位性は無いように思えます。
そうなると AppSync と API Gateway どちらを採用すれば良いのか迷いどころだと思いますが、わたしたちの AppSync 開発の知見をベースに本記事で解説しようと思います。
ズバッと言いますが、AppSync は GraphQL のエンドポイントを提供します。
API Gateway は複数のAPIエンドポイントを提供しますが、AppSync はGraphQL コードを受け付ける1つのエンドポイントしか提供しません。(1つのエンドポイントへ POST を受け付けるイメージ)
AppSync をバックエンドにすると下記のようなメリットがあります。
まず GraphQL の最大のメリットは、フロントエンドのエンジニアが手軽に API 開発に参加できることです。
それぞれざっくり下記のような開発フローとなります。
両者の最大の違いは、「デザイン起点設計」と「機能起点設計」です。
GraphQL の開発では、まず画面の振る舞いを決定し、そこからどのようなデータアクセスが必要か設計します。( DynamoDB と非常に相性が良いですね )
GraphQL は、デザイン駆動で作り始めるのがポイントです。
逆に言うとデザイン上に必要ないデータアクセスはスキーマ定義不要ですし、適切にデータアクセスを設計すれば、フロントエンドから一度の通信で全てのリソース情報を取得することも可能です。( DOM のマウント時に複数APIをコールして…..なんてことが軽減されます )
わたしたちは前述のように GraphQL と AppSync どちらを採用するか検討した後、GraphQL の場合は AppSync、Rest の場合は API Gateway を採用しています。
ただし、注意点なのは全ての API を GraphQL で作れるとは限らないということです。例えば「外部提供 API」の開発要件が発生した場合、第三者に GraphQL でコールしてくれと言ってもなかなか受け入れてくれませんので、RestAPI の口を個別に作る必要があります。(基本的には GraphQL に閉じて開発は行えます)
インターネットで調べると、Amplify 関連の記事がかなり多いと思います。Amplfiy は AWS 社としても1推しの GraphQL クライアントなので、迷ったらAmplify を採用して問題ないです。
ただし下記のようなケースでは Amplify ではなく AppSyncSDK を利用する必要があります
AppSyncSDK は Apollo を拡張したライブラリです、つまり Apollo に対して知見が高ければ AppSyncSDK を使用するのも1つだと言えます。(ほぼ Apollo のドキュメントを見て開発が可能なので慣れている人にとってはメリットが大きい)
わたしたちが感じる AppSync のデメリットは大きく2つあります。
特にマッピングテンプレートは慣れないとなかなか苦戦するかと思います。(シンタックス自体はシンプルなので、少し文法を抑えれば大丈夫ですが…)
例えば、AppSync → ElasticSearch のマッピングテンプレートでは、下記のようなコードになります。
## [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] Static Group Authorization Checks **
#set($isStaticGroupAuthorized = $util.defaultIfNull(
$isStaticGroupAuthorized, false))
## Authorization rule: { allow: groups, groups: ["admin"], groupClaim: "cognito:groups" } **
#set( $userGroups = $util.defaultIfNull($ctx.identity.claims.get("cognito:groups"), []) )
#set( $allowedGroups = ["admin"] )
#foreach( $userGroup in $userGroups )
#if( $allowedGroups.contains($userGroup) )
#set( $isStaticGroupAuthorized = true )
#break
#end
#end
## Authorization rule: { allow: groups, groups: ["customer"], groupClaim: "cognito:groups" } **
#set( $userGroups = $util.defaultIfNull($ctx.identity.claims.get("cognito:groups"), []) )
#set( $allowedGroups = ["customer"] )
#foreach( $userGroup in $userGroups )
#if( $allowedGroups.contains($userGroup) )
#set( $isStaticGroupAuthorized = true )
#break
#end
#end
## [End] Static Group Authorization Checks **
## No Dynamic Group Authorization Rules **
...
$util.toJson($context.result)
Cognito のユーザーグループを判別して利用できる API かチェックして上で、処理を実行しているサンプルです。(レスポンスマッピングテンプレート)
ただし、実は基本的なマッピングテンプレート(例えば Dynamo, ElasticSearch へのデータ出し入れ)は、AppSync コンソールで自動的に生成したコードを少し修正すれば手軽に作成することが可能です。慣れるまでは、AppSync コンソールと仲良くなっておくのも1つでしょう。
最近はUXに優れた WEB サービスが非常に多く、開発者は競合サービスに勝つために日々新しい UX を考えプロダクト改善するなんてことが多いのではないでしょうか。
データアクセス(UX)を起点として開発できるのが、AppSync/GraphQL
の魅力ですね。
わたしたちは、GraphQL の開発プロジェクトを強力にサポートします。お気軽にお声掛けください。
スモールスタート開発支援、サーバーレス・NoSQLのことなら
ラーゲイトまでご相談ください
低コスト、サーバーレスの
モダナイズ開発をご検討なら
下請け対応可能
Sler企業様からの依頼も歓迎