React NativeでAWSを使用する
AWSは、クラウドサービスのプロバイダーとして、テクノロジー業界でよく知られています。これには、コンピューティング、ストレージ、データベース技術、およびフルマネージドのサーバーレス製品が含まれます。AWSモバイルチームは、クラウドに接続されたモバイルおよびウェブアプリケーションを、より安全で、スケーラブルで、開発およびデプロイしやすくするために、お客様やJavaScriptエコシステムのメンバーと密接に協力してきました。私たちは完全なスターターキットから始めましたが、最近のいくつかの開発があります。
このブログ記事では、ReactおよびReact Native開発者にとって興味深いことについて説明します。
- AWS Amplify、クラウドサービスを使用するJavaScriptアプリケーション向けの宣言型ライブラリ
- AWS AppSync、オフラインおよびリアルタイム機能を備えたフルマネージドGraphQLサービス
AWS Amplify
React Nativeアプリケーションは、Create React Native AppやExpoのようなツールを使って非常に簡単にブートストラップできます。しかし、ユースケースをインフラストラクチャサービスに合わせようとすると、それらをクラウドに接続するのは難しい場合があります。たとえば、React Nativeアプリで写真をアップロードする必要があるかもしれません。これらはユーザーごとに保護されるべきでしょうか?それはおそらく、何らかの登録またはサインインプロセスが必要であることを意味します。独自のユーザーディレクトリが必要ですか、それともソーシャルメディアプロバイダーを使用していますか?おそらく、アプリはユーザーがログインした後、カスタムビジネスロジックでAPIを呼び出す必要もあります。
JavaScript開発者がこれらの問題を解決するのを支援するために、AWS Amplifyというライブラリをリリースしました。設計は、AWS固有の実装ではなく、タスクの「カテゴリ」に分割されています。たとえば、ユーザーが登録、ログイン、そしてプライベート写真をアップロードできるようにしたい場合、単にAuthとStorageカテゴリをアプリケーションに組み込むだけです。
import { Auth } from 'aws-amplify';
Auth.signIn(username, password)
.then(user => console.log(user))
.catch(err => console.log(err));
Auth.confirmSignIn(user, code)
.then(data => console.log(data))
.catch(err => console.log(err));
上記のコードでは、Amplifyが多要素認証(MFA)コードをメールまたはSMSで使用するなど、一般的なタスクをどのように支援するかの例を見ることができます。現在サポートされているカテゴリは次のとおりです。
- Auth: 認証情報の自動化を提供します。既成の実装は、署名にAWS認証情報を使用し、Amazon CognitoからOIDC JWTトークンを使用します。MFA機能などの一般的な機能がサポートされています。
- Analytics: 1行のコードで、認証済みまたは未認証のユーザーのトラッキングをAmazon Pinpointで取得できます。必要に応じて、カスタムメトリクスまたは属性のためにこれを拡張できます。
- API: AWS Signature Version 4を活用して、RESTful APIとの安全な対話を提供します。APIモジュールは、Amazon API Gatewayを使用したサーバーレスインフラストラクチャに最適です。
- Storage: Amazon S3でのコンテンツのアップロード、ダウンロード、リスト表示を簡素化するコマンドです。データは、ユーザーごとに公開またはプライベートコンテンツに簡単にグループ化できます。
- キャッシング (Caching): ウェブアプリとReact Native全体で、実装固有の永続性を使用するLRUキャッシュインターフェースです。
- i18nとロギング (i18n and Logging): 国際化とローカライズ機能、およびデバッグとロギング機能を提供します。
Amplifyの優れた点の1つは、特定のプログラミング環境向けに「ベストプラクティス」が設計に組み込まれていることです。たとえば、お客様やReact Native開発者との連携でわかったことの1つは、開発中に物事を迅速に機能させるために取られた近道が、本番スタックにまで及んでしまうことです。これらはスケーラビリティやセキュリティを損なう可能性があり、インフラストラクチャの再設計やコードのリファクタリングを強制する可能性があります。
開発者がこれを回避するのをどのように支援するかの一例は、AWS Lambdaによるサーバーレスリファレンスアーキテクチャです。これらは、バックエンドを構築する際にAmazon API GatewayとAWS Lambdaを一緒に使用するためのベストプラクティスを示しています。このパターンはAmplifyのAPIカテゴリにエンコードされています。このパターンを使用して、いくつかの異なるRESTエンドポイントと対話し、カスタムビジネスロジックのためにヘッダーをLambda関数にすべて渡すことができます。また、これらの機能を備えた新規または既存のReact NativeプロジェクトをブートストラップするためのAWS Mobile CLIもリリースしました。始めるには、npm経由でインストールし、構成プロンプトに従うだけです。
npm install --global awsmobile-cli
awsmobile configure
モバイルエコシステムに特化したエンコードされたベストプラクティスのもう1つの例は、パスワードセキュリティです。デフォルトのAuthカテゴリの実装は、ユーザー登録とサインインのためにAmazon Cognitoユーザープールを活用しています。このサービスは、認証試行中にユーザーを保護する方法としてSecure Remote Passwordプロトコルを実装しています。もしプロトコルの数学を読み込むことに興味があれば、グループを生成するために原始根に対してパスワードベリファイアを計算する際に、大きな素数を使用する必要があることに気づくでしょう。React Native環境では、JITが無効になっています。これにより、このようなセキュリティ操作のためのBigInteger計算のパフォーマンスが低下します。これを考慮して、プロジェクト内でリンクできるAndroidおよびiOSのネイティブブリッジをリリースしました。
npm install --save aws-amplify-react-native
react-native link amazon-cognito-identity-js
Expoチームが最新のSDKにこれを含めてくれたことにも興奮しています。これにより、イジェクトせずにAmplifyを使用できます。
最後に、React Native(およびReact)開発に特化して、Amplifyには、アプリへのサインアップやサインインなどの機能を簡単にラップするための高階コンポーネント(HOC)が含まれています。
import Amplify, { withAuthenticator } from 'aws-amplify-react-native';
import aws_exports from './aws-exports';
Amplify.configure(aws_exports);
class App extends React.Component {
...
}
export default withAuthenticator(App);
基盤となるコンポーネントも<Authenticator />として提供されており、UIを完全にカスタマイズできます。また、ユーザーのサインイン状態、MFA確認待ちの状態など、ユーザーの状態管理に関するいくつかのプロパティや、状態変化時に実行できるコールバックも提供されます。
同様に、さまざまなユースケースで使用できる一般的なReactコンポーネントが見つかります。これらは、たとえば、StorageモジュールでAmazon S3からすべてのプライベート画像を表示するなど、ニーズに合わせてカスタマイズできます。
<S3Album
level="private"
path={path}
filter={(item) => /jpg/i.test(item.path)}/>
前述のとおり、公開またはプライベートストレージオプションを使用して、多くのコンポーネント機能をprops経由で制御できます。ユーザーが特定のUIコンポーネントと対話したときに、分析を自動的に収集する機能さえあります。
return <S3Album track/>
AWS Amplifyは、グローバルな初期化ルーチンまたはカテゴリレベルでの初期化を備えた、設定よりも規約重視の開発スタイルを好みます。開始する最も簡単な方法は、aws-exportsファイルを使用することです。ただし、開発者は既存のリソースと独立してライブラリを使用することもできます。
哲学を深く掘り下げて完全なデモを見るには、AWS re:Inventのビデオをご覧ください。
AWS AppSync
AWS Amplifyのローンチ直後、AWS AppSyncもリリースしました。これは、オフライン機能とリアルタイム機能の両方を備えたフルマネージドのGraphQLサービスです。GraphQLはさまざまなクライアントプログラミング言語(ネイティブのAndroidやiOSを含む)で使用できますが、React Native開発者の間で非常に人気があります。これは、データモデルが一方向データフローとコンポーネント階層にうまく適合するためです。
AWS AppSyncを使用すると、独自のAWSアカウントのリソースに接続できるため、データの所有権と制御はユーザーにあります。これはデータソースを使用して行われ、サービスはAmazon DynamoDB、Amazon Elasticsearch、およびAWS Lambdaをサポートしています。これにより、単一のGraphQL APIでスキーマとして機能(NoSQLや全文検索など)を組み合わせることができます。これにより、データソースを自由に組み合わせることができます。AppSyncサービスはスキーマからプロビジョニングすることもできるため、AWSサービスに慣れていない場合でも、GraphQL SDLを記述してボタンをクリックするだけで、自動的に起動して実行できます。
AWS AppSyncのリアルタイム機能は、よく知られたイベントベースのパターンを持つGraphQLサブスクリプションを通じて制御されます。AWS AppSyncのサブスクリプションは、GraphQLディレクティブを持つスキーマで制御され、スキーマは任意のデータソースを使用できるため、Amazon DynamoDBとAmazon Elasticsearch Serviceでのデータベース操作、またはAWS Lambdaを使用したインフラストラクチャの他の部分から通知をトリガーできます。
AWS Amplifyと似た方法で、AWS AppSyncを使用してGraphQL APIのエンタープライズセキュリティ機能を使用できます。このサービスを使用すると、APIキーですばやく開始できます。ただし、本番環境に移行する際には、AWS Identity and Access Management (IAM) またはAmazon CognitoユーザープールからのOIDCトークンを使用するように移行できます。型に対するポリシーを使用して、リゾルバーレベルでアクセスを制御できます。実行時にきめ細かなアクセス制御チェックのために論理チェックを使用することもできます。たとえば、ユーザーが特定のデータベースリソースの所有者であるかどうかを検出するなどです。また、リゾルバーの実行または個々のデータベースレコードへのアクセスに対するグループメンバーシップのチェックに関する機能もあります。
React Native開発者がこれらのテクノロジーについてさらに学ぶのを支援するために、AWS AppSyncコンソールのホームページで起動できる組み込みのGraphQLサンプルスキーマがあります。このサンプルは、GraphQLスキーマをデプロイし、データベーステーブルをプロビジョニングし、クエリ、ミューテーション、およびサブスクリプションを自動的に接続します。また、この組み込みスキーマを活用するAWS AppSync用の動作するReact Nativeの例(およびReactの例)もあり、クライアントとクラウドの両方のコンポーネントを数分で実行できます。
AWSAppSyncClientを使用すると、Apollo Clientにプラグインするため、簡単に開始できます。AWSAppSyncClientは、GraphQL APIのセキュリティと署名、オフライン機能、およびサブスクリプションのハンドシェイクとネゴシエーションプロセスを処理します。
import AWSAppSyncClient from "aws-appsync";
import { Rehydrated } from 'aws-appsync-react';
import { AUTH_TYPE } from "aws-appsync/lib/link/auth-link";
const client = new AWSAppSyncClient({
url: awsconfig.graphqlEndpoint,
region: awsconfig.region,
auth: {type: AUTH_TYPE.API_KEY, apiKey: awsconfig.apiKey}
});
AppSyncコンソールは、GraphQLエンドポイント、AWSリージョン、APIキーを含む設定ファイルをダウンロード用に提供します。その後、React Apolloでクライアントを使用できます。
const WithProvider = () => (
<ApolloProvider client={client}>
<Rehydrated>
<App />
</Rehydrated>
</ApolloProvider>
);
この時点で、標準のGraphQLクエリを使用できます。
query ListEvents {
listEvents{
items{
__typename
id
name
where
when
description
comments{
__typename
items{
__typename
eventId
commentId
content
createdAt
}
nextToken
}
}
}
}
上記の例は、AppSyncによってプロビジョニングされたサンプルアプリのスキーマを使用したクエリを示しています。DynamoDBとの対話だけでなく、データ(暗号化されたトークンを含む)のページネーションや、EventsとComments間のタイプリレーションも含まれています。アプリはAWSAppSyncClientで構成されているため、データは自動的にオフラインで永続化され、デバイスが再接続すると同期されます。
このビデオで、この背後にあるクライアントテクノロジーの深掘りおよびReact Nativeのデモをご覧いただけます。
フィードバック
ライブラリの背後にあるチームは、これらのライブラリとサービスがどのように機能しているかをお聞きすることを熱望しています。また、クラウドサービスでのReactおよびReact Native開発をより簡単にするために、他に何ができるかについても知りたいと思っています。AWS AmplifyまたはAWS AppSyncについて、GitHubでAWSモバイルチームにお問い合わせください。
