We’re sorry we missed you at re:Invent, but we can still meet!

Momento フロントエンド開発者のとっておきの秘密

ブラウザから直接、低レイテンシーで自動スケーリングのウェブサーバーに瞬時にアクセスできます。

アレン・ヘルトン
著者

Share

私はフロントエンドの開発者にはあまり興味がなかった。私のキャリアを通じて、私の焦点はバックエンドにありました。システムを設計し、データモデルを構築し、イベント駆動型のワークフローを振り付けるのが好きです。大学を卒業してからずっと挑戦し続けてきた、満足のいく問題群です。

しかし、2023年の初めにMomentoで働き始めたとき、状況は変わりました。ユーザー向けのデモを作ることが多くなり、私が慣れ親しんだスタイルのないdivよりも見栄えのするウェブページが必要になったのです。そこで当然、開発者なら誰でもそうするように、私はChatGPTにNext.jsでアプリを作る方法を教えてくれるよう頼みました。私はReactを少し学び、数ヶ月かけてフロントエンド開発のコツを掴みました。フロントエンドの開発はバックエンドと同じくらい難しいのです!

もちろん課題はさまざまで、何かを作り上げるのに苦労しているうちに、「思うように進まない」ことがよくあります。しかし、MomentoがWeb SDKをリリースしたとき、誰かが私に簡単なボタンをくれたような気がしました。いや、仕事だからそう言っているのではありません。本当に簡単なんです。説明しましょう。

バックエンドを構築せずにバックエンド機能を実現

OK、このセクションのヘッダーは嘘のように聞こえます。しかし、そうではありません!Momento Web SDKをReact、Angular、Vue、Astroなど好きなUIフレームワークで使えば、マネージドサーバーレスサービスをビルドすることなく利用できます。シンプルなAPIコールだけで、キャッシュと管理されたWebSocketにアクセスできます。

つまり、Momento キャッシュを使えば、API 呼び出しのキャッシュ、ユーザーセッションストアの構築、リモートロケーションへのファイルの一時保存など、データベースのような機能に直接アクセスできるようになります。多くのフロントエンドフレームワークでは、セッションやローカルストレージを使ってこれらのことができますが、ブラウザに縛られています。Momentoを使えば、その制約がなくなります。クロスブラウザセッションやクロスマシンにも対応できます。

Momentoは、一時的なデータを保存し、WebSocket接続を管理するための個人的な高速Webサーバーとして機能します。

Momentoへのデータ転送とMomentoからのデータ転送にのみ課金され、毎月5GBの無料ティアがあります。

セッションデータ

ユーザーデータのローカルストレージのTTLをチェックして検証する代わりに、Momentoキャッシュに保存し、キャッシュミスが発生したときにデフォルトを処理するだけです。


const response = await cacheClient.dictionaryGetField('user-sessions', userId, 'fullName');
if (response instanceof CacheDictionaryGetField.Hit) {
    return response.value();
} else { // load from API
    const data = await axios.fetch(`/api/users/${userId}`);
    const user = await data.json();
    cacheClient.dictionarySetFields('user-sessions', userId, userData);
    return user.fullName;
}

JSONオブジェクト全体を辞書に格納し、(ほとんど)GraphQL APIのように、必要なだけの情報を取得することができます。これは、ユーザーに関する情報を読み込む際に、非常に強力になります。このディクショナリキャッシュアイテムにフィールドを追加し続け、どのマシンからでも詳細をフェッチできるため、システム内の他のユーザーがミリ秒単位でデータにアクセスできるようになります。

カンファレンスでMomentoのブースを訪れたことがある人なら、私たちが運営するゲームも同じようなパターンを使っています。実際、キャッシュを唯一のデータストアとして使用しており、データベースは一切ありません。ソースコードをご覧ください。

ファイルのシェア

誰かとセキュアにファイルを共有する必要があるけれど、ウェブサーバーの構築やhttpsの設定、ストレージの設定方法がわからないという経験はないでしょうか?私もそうです(イエスと答えたと仮定して)。朗報です。それもわずか数行のコードで済むようになりました。


const buffer = fs.readFileSync(filePath);
await client.set('files', fileName, new Uint8Array(buffer.buffer), { ttl: 600 });

キャッシュに画像がセットされていれば、そのキャッシュキーを明示的にスコープしたトークンを作成し、トークンを保持する場所への一時的なアクセスを許可することができます。

const scope = {
    permissions: [
        {
            role: 'readonly',
            cache: 'files',
            item: {
                key: fileName
            }
        }
    ]
};

const token = await authClient.generateDisposableToken(scope, ExpiresIn.minutes(10));
return token.authToken;

この例では、ファイルは10分間しか利用できないので、安全なデータが古くなったり、知らないうちにどこかのサーバーに残されたりする心配はありません。自動で付与される生存時間(TTL)により、追加作業なしでファイルは削除されます。

ファイル共有アプリの完全な例については、リファレンス・アプリケーションをご覧ください。

チャット

フロントエンドフレームワークとMomentoだけで、チャットアプリ全体を構築できます!ユーザーとメッセージをキャッシュアイテムに保存し、メッセージが送信されたらMomento Topicsにパブリッシュして通知します。長い認証メカニズムや接続管理、データベースは必要ありません。短時間のセッションベースのチャットを作成したい場合、これは完璧なソリューションです。

チャットルームにメッセージが送信されると、それらをリストキャッシュアイテムに保存することができます。このタイプのキャッシュアイテムは時系列に保存されるので、スレッドセーフにすべてのメッセージの履歴を送信された順に保存することができます。


const msg = JSON.stringify({ username: name, message: message });    
cacheClient.listPushFront('chat', router.query.room, msg);

部屋に出入りする人をキャッシュ・アイテムに追加します。このアイテムタイプは、異なるアイテムの順序なし配列を保存します。つまり、あるユーザーがネットワーク接続に問題があり、退室と再入室を繰り返したとしても、大丈夫です。


cacheClient.setAddElement('chat', `${router.query.room}-users`, username);

誰かがチャットメッセージを入力し、”Enter “ボタンを押した後、1回の呼び出しでチャットルームの全員にメッセージを公開し、新しいメッセージを即座に通知することができます。

const msg = { username, message, timestamp: new Date().toISOString() }; 
topicClient.publish('chat', router.query.room, JSON.stringify(msg));

チャットルームには様々な種類があります。私たちがVercelで行った完全なビルドと付随するソースコードに関する私たちのブログポストをチェックしてください。

双方向なインタラクティブなサイト

ウェブページをロードし、自分のものではないマウスが画面をズームするのを見ることほど気まぐれなことはありません。コラボレーション・プラットフォームは大流行しており、WebSocketのサポートなしでは実現できません。しかし、WebSocketを構築するのは難しく、サーバーサイドのコンポーネントが必要になります。Momentoは違います

Momento Topicsを使用すると、フロントエンドとフロントエンド、バックエンドとフロントエンド、さらにはバックエンドとバックエンドを接続することができます。イベントの生成や消費に制限はありません。つまり、サーバーサイドのコンポーネントなしで、リアクションを送信したり、コラボレーションセッションを構築したり、アプリをゲーム化したりできるのです!

メッセージを送信するにはトピックに発行し、イベントが発生したらイベントハンドラを登録するにはサブスクライブするだけです。チャットの例で、メッセージをパブリッシュするのがいかに簡単かをすでに見てきました。サブスクライブは、メッセージを受信したときとエラーが発生したときにイベントハンドラを設定するのと同じくらい簡単です:


useEffect(() => {
    async function subscribeForReactions() {
        const sub = await topicClient.subscribe('reactions', name, {
            onItem: (message) => { sendReaction(message.valueString()) },
            onError: (err) => { console.error(err) }
        });
        setSubscription(sub);
    }

    subscribeForReactions();
    return () => {
        subscription?.unsubscribe();
    }
}, []);

イベントハンドラは完全にあなた次第なので、メッセージに反応して好きなことをすることができます!実用的な例として、このコードが使われた私のライブリアクションアプリをご覧ください。

結論

フロントエンドでできるクールなことは山ほどあります。車輪の再発明に時間を費やし、独自のキャッシュ・メカニズムや別のWebSocket実装を構築する必要はないでしょう。代わりに、あなたのためにすべてを行い、あなたのブラウザから直接、自動スケーリング、超低遅延ウェブサーバにアクセスできるサービスを使いましょう(しかも安全です)!

これは時間の大幅な節約になるだけでなく、総所有コストも大幅に削減できることがわかりました。APIが構築されるのをバックエンド・チームと行ったり来たりする必要はありません。新しいことを試すためにインフラが立ち上がるのを待つこともありません。予定されたダウンタイムもありません。私たちのチームは、可動部分を大幅に減らしています。これがフロントエンドのサーバーレス・サービスです。

セキュリティについて簡単に触れておきましょう。覚えておいてほしいのは、長寿命のAPIキーをブラウザに渡してはいけないということです。その代わりに、トークン、つまりブラウザに最適な短命でスコープが限定された値を選ぶことです。

Momentoを始めるのは無料です!GmailやGitHubのアカウントでサインインすれば、すぐに使い始めることができます!あなたが作ったものをぜひ見てください!私たちのDiscordに飛び込んできて、挨拶してください。

Happy coding! 

Share