メインコンテンツまでスキップ

ブラウザでJavaScriptを使用するためのMomento Web SDK

Momentoは2つのJavaScript SDKを提供しています; 1つはNode.js用、もう1つはブラウザの他のWebアプリケーション用(このページ)です。2つのSDKは同じAPIを持っているので、importステートメントを除いてコードは同じように見えますが、異なるJavaScript実行環境において最適なパフォーマンスと互換性を保つように作られています。

Node.js SDKはサーバーサイドでの使用に最適です。しかし、Momento Web SDKでは、開発者はブラウザで実行され、Momentoサービスと直接通信するJavaScriptコードを記述することができます。これにより、ブラウザとMomento間のキャッシュやPub/Subコールを仲介するために、独自のウェブサービスを構築・運用する一般的なオーバーヘッドを回避することができます。また、ウェブトラフィックのホップが1つ減るので、ブラウザアプリケーションのパフォーマンスをさらに向上させることができます。両方の長所を兼ね備えています!

また、Node.js以外のJavaScript環境でもWeb SDKを使用できます。

Momento web SDKはnpmパッケージ@gomento/sdk-webから利用できます。

ソースコードはGitHubにあります: momentohq/client-sdk-javascript

必要条件

Resources

  • Getting started with Momento Cache in JavaScript: このチート・シートはNode.js SDKを対象としていますが、Web SDK APIは完全に互換性があります。
  • Getting started with Momento Topics in JavaScript: このチート・シートはNode.js SDKを対象としていますが、Web SDK APIは完全に互換性があります。
  • Chat app: Next.js: は、キャッシュとトピック名を入力することで、ユーザーがブラウザ上でチャットを行うことを可能にするダイナミック・アプリである。このアプリケーションは、トピックを購読するために使用されるブラウザに、スコープが低く寿命の短い認証トークンを提供します。
  • Chat app: Vite: チャットアプリの静的バージョンは、ブラウザに認証トークンを提供するために別のAPI(私たちのNode.jsトークン自動販売機など)を必要とします。
  • Web SDK Examples: ウェブSDKの使い方を説明するサンプルプロジェクト

Momento web SDKとMomentoトピックス

Momento Topicsは、ブラウザでのパブリッシャーとサブスクライバーの通信を大幅に簡素化します。従来、この開発者の例は、ウェブサイトに組み込まれたチャット・アプリケーションです。ブラウザ用のクライアント・コードだけでなく、すべての通信をルーティングするためのサーバ・サイド・コードも構築することになります。

Momento Web SDKにMomento Topicsを組み込むことで、このサーバーサイドの複雑さが解消されます。開発者はブラウザから直接 Momento Topics を購読できます。そして、Momento は、トピックにメッセージが発行されたときのすべての通信を処理し、WebSocket 用のカスタムサーバーサイドインフラストラクチャを不要にします!

ブラウザ用ウェブSDKの使用

APIコールはMomento Node.js SDKと同じですが、import/require文は(Node.js SDKである)@gomento/sdkの代わりに、npmから@gomento/sdk-webパッケージを消費します。

以下は、ウェブSDKのインポート文の例です:

import {CacheClient} from ‘@gomomento/sdk-web’;

ブラウザ用認証情報

ブラウザアプリケーションが Momento サービスと通信するためには、ブラウザに Momento 認証トークンを提供する必要があります。 推奨される方法は、ブラウザセッションごとに有効期限付きのMomento使い捨てトークンを生成することです。これにより、データが漏えいする心配なく、トークンを配布することができます。

ブラウザで使用するMomento使い捨てトークンを作成するには、一般的に"トークン自動販売機"コンポーネントが必要です。トークン自動販売機は、静的なウェブサイトがアクセスできるHTTPエンドポイントを持つスタンドアロンアプリケーションにすることもできますし、Next.jsチャットアプリの例のように、ウェブアプリケーションのサーバーサイドに埋め込むこともできます。

いずれの場合も、Node.js SDK を使用して Momento AuthClient をインスタンス化し、Momento Console 経由で生成された Super User スコープの API キーを提供することになるでしょう:

new AuthClient({
credentialProvider: CredentialProvider.fromEnvironmentVariable({
environmentVariableName: 'MOMENTO_API_KEY',
}),
});

次に、generateDisposableToken API を使用して使い捨てトークンを作成し、ブラウザに送信します。これらのトークンはデフォルトでは短命で、1時間以内に失効しなければなりません。

// Generate a disposable token with read-write access to a specific key in one cache
const oneKeyOneCacheToken = await authClient.generateDisposableToken(
DisposableTokenScopes.cacheKeyReadWrite('squirrels', 'mo'),
ExpiresIn.minutes(30)
);
if (oneKeyOneCacheToken instanceof GenerateDisposableToken.Success) {
console.log('Generated a disposable API key with access to the "mo" key in the "squirrels" cache!');
// logging only a substring of the tokens, because logging security credentials is not advisable :)
console.log(`API key starts with: ${oneKeyOneCacheToken.authToken.substring(0, 10)}`);
console.log(`Expires At: ${oneKeyOneCacheToken.expiresAt.epoch()}`);
} else if (oneKeyOneCacheToken instanceof GenerateDisposableToken.Error) {
throw new Error(
`An error occurred while attempting to call generateApiKey with disposable token scope: ${oneKeyOneCacheToken.errorCode()}: ${oneKeyOneCacheToken.toString()}`
);
}

// Generate a disposable token with read-write access to a specific key prefix in all caches
const keyPrefixAllCachesToken = await authClient.generateDisposableToken(
DisposableTokenScopes.cacheKeyPrefixReadWrite(AllCaches, 'squirrel'),
ExpiresIn.minutes(30)
);
if (keyPrefixAllCachesToken instanceof GenerateDisposableToken.Success) {
console.log('Generated a disposable API key with access to keys prefixed with "squirrel" in all caches!');
// logging only a substring of the tokens, because logging security credentials is not advisable :)
console.log(`API key starts with: ${keyPrefixAllCachesToken.authToken.substring(0, 10)}`);
console.log(`Expires At: ${keyPrefixAllCachesToken.expiresAt.epoch()}`);
} else if (keyPrefixAllCachesToken instanceof GenerateDisposableToken.Error) {
throw new Error(
`An error occurred while attempting to call generateApiKey with disposable token scope: ${keyPrefixAllCachesToken.errorCode()}: ${keyPrefixAllCachesToken.toString()}`
);
}

// Generate a disposable token with read-only access to all topics in one cache
const allTopicsOneCacheToken = await authClient.generateDisposableToken(
TokenScopes.topicSubscribeOnly('squirrel', AllTopics),
ExpiresIn.minutes(30)
);
if (allTopicsOneCacheToken instanceof GenerateDisposableToken.Success) {
console.log('Generated a disposable API key with access to all topics in the "squirrel" cache!');
// logging only a substring of the tokens, because logging security credentials is not advisable :)
console.log(`API key starts with: ${allTopicsOneCacheToken.authToken.substring(0, 10)}`);
console.log(`Expires At: ${allTopicsOneCacheToken.expiresAt.epoch()}`);
} else if (allTopicsOneCacheToken instanceof GenerateDisposableToken.Error) {
throw new Error(
`An error occurred while attempting to call generateApiKey with disposable token scope: ${allTopicsOneCacheToken.errorCode()}: ${allTopicsOneCacheToken.toString()}`
);
}

// Generate a disposable token with write-only access to a single topic in all caches
const oneTopicAllCachesToken = await authClient.generateDisposableToken(
TokenScopes.topicPublishOnly(AllCaches, 'acorn'),
ExpiresIn.minutes(30)
);
if (oneTopicAllCachesToken instanceof GenerateDisposableToken.Success) {
console.log('Generated a disposable API key with access to all topics in the "squirrel" cache!');
// logging only a substring of the tokens, because logging security credentials is not advisable :)
console.log(`API key starts with: ${oneTopicAllCachesToken.authToken.substring(0, 10)}`);
console.log(`Expires At: ${oneTopicAllCachesToken.expiresAt.epoch()}`);
} else if (oneTopicAllCachesToken instanceof GenerateDisposableToken.Error) {
throw new Error(
`An error occurred while attempting to call generateApiKey with disposable token scope: ${oneTopicAllCachesToken.errorCode()}: ${oneTopicAllCachesToken.toString()}`
);
}

DisposableTokenScope や認可のためのパーミッションオブジェクトなど、Momento トークンの詳細については、Auth API リファレンス を参照してください。

FAQ

ブラウザからのトラフィックは暗号化されていますか?
Momentoサービスのすべてのトラフィックと同様に、Web SDKはワイヤ上で完全に暗号化されています。さらに、SDKはTLS 1.2+暗号化を使用しています。