React NativeでAWSを使用する
AWSは、クラウドサービスのプロバイダーとしてテクノロジー業界でよく知られています。これには、コンピューティング、ストレージ、データベース技術のほか、完全に管理されたサーバーレスサービスも含まれます。AWS Mobileチームは、クラウドに接続されたモバイルおよびウェブアプリケーションをより安全でスケーラブルにし、開発とデプロイを容易にするために、お客様と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つは、開発中に物事を迅速に機能させるためにとられたショートカットが、本番環境にまで及ぶ可能性があることでした。これらはスケーラビリティまたはセキュリティを損ない、インフラストラクチャの再設計とコードのリファクタリングを強制する可能性があります。
開発者がこれを回避するのを支援する方法の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
モバイルエコシステムに特化した、組み込まれたベストプラクティスの別の例は、パスワードのセキュリティです。デフォルトのAuth
カテゴリの実装は、ユーザー登録とサインインにAmazon Cognitoユーザープールを活用しています。このサービスは、認証試行中にユーザーを保護する方法として、Secure Remote Passwordプロトコルを実装しています。プロトコルの数学を読み進めると、Groupを生成するために原始根に対してパスワードベリファイアを計算するときに、大きな素数を使用する必要があることに気づくでしょう。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);
基盤となるコンポーネントは
としても提供されており、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をサポートしています。これにより、NoSQLや全文検索などの機能を1つのGraphQL APIでスキーマとして組み合わせることができます。これにより、データソースを自由に組み合わせることができます。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の例)もあり、クライアントとクラウドコンポーネントの両方を数分で実行できます。
Apollo ClientにプラグインするAWSAppSyncClient
を使用すると、開始は簡単です。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 Mobileチームにご連絡ください。