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

Hello World! Momento Web SDKのご紹介

今までにないインスタント通知と簡単なキャッシュアクセスにご挨拶しましょう。当社の新しいWeb SDKを使えば、開発者は強力なリアルタイム機能を簡単に統合でき、より高速なパフォーマンスと新しい機能をエンドユーザーに提供できます。

Allen Helton
Author

Share

何が素晴らしいか分かりますか?フロントエンド・アプリケーションでパワフルなSDKを使うことです。ただ動くだけで、ほとんどの作業をやってくれるSDKを使うたびに、私は大喜びします。楽しいユーザー・エクスペリエンスを構築するのは、それだけで十分難しいのに、なぜ自分で何かを再発明する方が難しいのでしょうか?

それが、最新の製品であるMomento Web SDKを開発する際に私たちが考えたことです!汎用性とパフォーマンスを念頭に置いて設計されたこのSDKの目的は、Momento Cacheとトピックをこれまで以上にエンドユーザーに近づけることです。お客様のブラウザ環境でシームレスに機能し、スムーズで一貫性のある開発体験をお約束します。

興奮しますか?私たちもです!このリリースでアンロックされたクールな新機能のいくつかをチェックしてください👇。

・チャネルベースのウェブソケット
・クライアントとサーバー間の共有キャッシュ
・ブラウザ間通信
・APIトークンのプログラムによる生成

新しく開かれたドア

私にとっては、これらはかなり気の利いた能力です。しかし、実生活でどのように使うことができるかを話してみないと、インパクトは伝わりません。それでは、私たちがどのようにゲームを変えたかについてお話ししましょう。

ここ数ヶ月の間に、Momentoでチャットアプリケーションを構築するのがいかに簡単かについて、いくつかのコンテンツを作成しました。Web SDK のリリースにより、さらに簡単になりました。

サーバーサイドAPIの実装を忘れ、チャットを完全にMomentoに収めます。Momentoは、WebSocket接続の管理、データの配信、チャット履歴の一時保存を行います。

しかし、デモに入る前に、部屋の中の象について話す必要がある。認証です。

ウェブでの認証

ウェブ開発における重要な課題のひとつは、安全で効率的な認証を確保することです。長寿命のAPIトークンをブラウザに渡すことは、大きな禁じ手です。悪意のあるユーザーがトークンを横取りし、あなたのアカウントを永久に自由に支配してしまう可能性があるからです。それは避けたい。誰もそんなことは望んでいません。

今日まで、ユーザーはMomento Consoleにログインし、ユーザーインターフェイスから有効期限付きのAPIトークンを生成することができました。設定可能な時間、たとえば 1 時間が経過すると、API トークンは無効になり、使用できなくなります。このタイプのトークンはウェブ開発のための解決策ですが、コンソールから手動でこれらのトークンを取得することはできません。

ブラウザでの安全なトークン使用をサポートするため、Node.js SDK を更新し、期限切れトークンのプログラムによるリフレッシュを可能にしました。これらのトークンは、自由に無効化できるように設定されているだけでなく、悪意のあるユーザーを寄せ付けないように、制限された権限セットでスコープされています。プログラムで生成されたトークンは、キャッシュの作成、キャッシュの削除、他のAPIトークンの作成などのコントロールプレーン操作にアクセスできません。これによりセキュリティが強化され、ユーザー・データの安全性に関して安心感を与えることができます。

Momento上でアプリケーションを構築する際、個々のユーザーセッションに対して短命で限定されたパーミッションのトークンを配布するトークン・ベンディング・マシーン(TVM)を作成できるようになりました。

最も簡単なチャット方法

さて、いよいよ本題です。インスタント・メッセージングをアプリに追加するのがいかに簡単かをお見せするために、私たちの新しいWeb SDKを使ってチャット・アプリのサンプルを作ってみました。

アプリケーションのホームページを読み込むと、トークン自動販売機への呼び出しが行われ、セッション用の Momento API トークンが取得されます。トークンと有効期限をクレームオブジェクトに追加し、ユーザーに返します。


async function getClaims(ip) {
  let claims = {};
  const cacheClient = await getCacheClient();
  const response = await cacheClient.get('user', `${ip}-claims`);
  if (response instanceof CacheGet.Hit) {
    claims.momento = JSON.parse(response.valueString());
  } else {
    const authClient = getAuthClient();

    const token = await authClient.generateAuthToken(AllDataReadWrite, ExpiresIn.seconds(3600));
    if (token instanceof GenerateAuthToken.Success) {
      claims.momento = {
        token: token.authToken,
        exp: token.expiresAt.epoch
      };

      await cacheClient.set('user', `${ip}-claims`, JSON.stringify(claims.momento), { ttl: 3600 });
    }

  }
  return claims;
};

このコードは、/userinfoエンドポイントをバックするLambda関数内で実行されます。Node.js SDKを使用しており、サーバーサイドの操作を想定しています。生成された認証トークンをIPアドレスごとにキャッシュしているので、同じIPから複数の呼び出しがあった場合、認証情報を再利用して不必要にトークンが生成されるのを防ぐことができます。‍

これが、私たちがチャットアプリのために生成した唯一のサーバーサイドのコードです!それ以外はすべてフロントエンドアプリケーションにあり、Web SDKを介してMomentoサーバーと直接通信します。チャットルームを開くときのコードを見てみましょう。

useEffect(() => {
  async function setupMomento() {
    initializeTopicClient();
    initializeCacheClient();
    loadChatHistory();
  }

  if (credentials) {
    setupMomento();
  }
}, [credentials, router]);

const initializeTopicClient = async () => {
  if (!topicClient && router.query.room) {
    topicClient = new TopicClient({
      configuration: Configurations.Browser.v1(),
      credentialProvider: CredentialProvider.fromString({ authToken: credentials.user.claims.momento.token })
    });

    updateTopicClient(topicClient);
    await topicClient.subscribe('chat', `${router.query.room}-chat`, {
      onItem: async (data) => await saveMessage(data.value()),
      onError: (err) => console.log(err)
    });
  }
};

const loadChatHistory = async () => {
  const chatHistoryResponse = await cacheClient.listFetch('chat', router.query.room);
  if (chatHistoryResponse instanceof CacheListFetch.Hit) {
    const history = chatHistoryResponse.valueListString().map(msg => JSON.parse(msg));
    updateMessages(history);
  }
};

Next.jsのチャットアプリでは、認証情報が設定されるたびにブラウザでスクリプトを実行します。このスクリプトは Momento Web SDK の TopicClient を初期化し、動的トピック ${router.query.room}-chat をサブスクライブします。これにより、そのチャットルーム専用のチャンネルへの接続が確立され、行き交うすべてのメッセージがピックアップされます。

また、チャット履歴もキャッシュからロードします。以前の実装のように、すべてのチャットメッセージはMomentoリストに保存されます。チャットメッセージが送信されると、そのメッセージはリストにプッシュされるので、参加した人は誰でも送信された順にチャット履歴にアクセスすることができます。

しかし、今メッセージを送るとどうなるのでしょうか?以前は、私たちが管理するWebSocketサーバーに行くWebSocket接続を介してメッセージを公開していました。確かにそれはまだあるのでしょうか?

いや。今はずっと簡単です。

const sendMessage = async (event) => {
  event.preventDefault();

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

  setMessage("");
};

const sendMessage = async (event) => {
  event.preventDefault();

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

  setMessage("");
};

それだけです。必要なコードはこの5行だけです。これは、あなたがチャットアプリケーションで “送信 “ボタンを押すか、Enterキーを押したときに実行されます。あなたのユーザー名とメッセージでJSONオブジェクトを作成し、チャットルームのトピックに公開します。公開後、チャット履歴に追加して完了です!

メッセージの受信も同じように簡単です。

const saveMessage = async (newMessage) => {
  const detail = JSON.parse(newMessage);
  updateMessages([detail, ...messagesRef.current]);
};

これは、チャットルームのトピックを購読するときに設定したイベントハンドラです。新しいメッセージをステートオブジェクトに追加し、それを画面にレンダリングする以外には何もしません。とてもクールです!

完全な実装については、GitHubにある完全なソースコードをチェックすることを強くお勧めします。

その他のクールなこと

サーバーサイドのコードとブラウザーを直接接続できるようになった今、管理不要で利用できるクールな新機能がたくさんあります:

・ロケーショントラッキング
・リアルタイムデータ更新
・オンラインプレゼンス指標
・ライブ統計トラッキング

私たちMomentoは、新しいWeb SDKをお届けし、多くの新しい可能性とユースケースへの扉を開くことができ、大変嬉しく思っています。ツイートで収まるようなシンプルな価格設定で、最先端のサーバーレス・ソリューションをお届けしていきますので、ご期待ください。

あなたの制限を解除しましたか?上記にない面白いアイデアがありますか?ぜひお聞かせください!私たちのDiscordに飛び込んできてください!準備ができたら、まずはドキュメントをご覧ください。

Happy coding!

Share