Redis
 Computer >> コンピューター >  >> プログラミング >> Redis

UpstashRedisをRemixのセッションストアとして使用する

フルスタックのWebフレームワークとして、Remixは一般的なWebサーバーのユースケースを処理するためのAPIを提供します。この投稿では、セッションと、Upstashを使用してセッションを保存する理由と方法に焦点を当てます。

セッションとは何ですか?

Remixドキュメントには、セッションの非常に優れた紹介がありますhttps://remix.run/docs/en/v1/api/remix#sessions

一言で言えば、セッションは、サーバーとクライアントがユーザーデータ/状態を共有できるようにするメカニズムです。セッションの使用例としては、ユーザー認証の状態、ショッピングカートのステータス、フラッシュメッセージなどの追跡があります。

UpstashRedisを使用する理由

セッションデータはサーバーに保存されます。サーバーレスインフラストラクチャまたは一部のPASSインフラストラクチャ(Herokuなど)にデプロイする場合、リクエスト(サーバーレス)またはデプロイ(PASS)ごとにデータが変更される可能性があるため、サーバーのファイルシステムにデータを永続化することはできません。データを永続化するには、ユーザーデータを外部データベースに保存する必要があります。 Upstash Redis DBは、次の理由でセッションデータを保存するための優れたソリューションです。

  • Redisセッションと同様に、本質的にkey:valueがあります キーがセッションのIDであり、値がシリアル化されたデータであるデータ構造。
  • Redisには、期限切れのセッションをクリーンアップする必要性を減らす組み込みの期限切れメカニズムがあります。
  • セッションは機密性の高いユーザーデータを保持する場合があり、UpstashRedisは保存されているすべてのデータを暗号化します。
  • Upstashは単純なHTTPRESTAPIを使用しています。 HTTPは、サーバーレスインフラストラクチャから通信する最も簡単な方法です。

RedisでUpstashをセッションプロバイダーとして使用する方法

この投稿は、私が書いたUpstashの例を使用したRedisセッションストレージに基づいています。 Remixリポジトリのクローンを作成して、試してみてください。

ステップ1-UpstashAPIキーを取得します
  • https://upstash.com/にアクセスして新しいアカウントを作成します
  • 新しいRedisDBを作成する
  • UPSTASH_REDIS_REST_URLをコピーします &UPSTASH_REDIS_REST_TOKEN それらを.envというファイルに保存します Remixプロジェクトのルートにあります。
  • dotenvをインストールします -$ npm install --save-dev dotenv -これにより、.envから環境変数を挿入できるようになります 作成したファイル。
  • Go to you package.json ファイルを作成し、devを置き換えます スクリプトフォームremix dev dotenv/config node_modules/.bin/remix devへ 。

ステップ2-コアのcreateSessionStorageを実装します Upstashセッションの実装を作成するには

Remixは、createSessionStorageを使用して独自のセッション統合を構築するための優れたAPIを提供します 。この関数を実装してUpstashを統合しましょう。

// sessions/upstash.server.ts

import * as crypto from "crypto";

import { createSessionStorage } from "remix";

const upstashRedisRestUrl = process.env.UPSTASH_REDIS_REST_URL;

const headers = {
  Authorization: `Bearer ${process.env.UPSTASH_REDIS_REST_TOKEN}`,
  Accept: "application/json",
  "Content-Type": "application/json",
};

const expiresToSeconds = (expires) => {
  const now = new Date();
  const expiresDate = new Date(expires);
  const secondsDelta = expiresDate.getSeconds() - now.getSeconds();
  return secondsDelta < 0 ? 0 : secondsDelta;
};

// For more info check https://remix.run/docs/en/v1/api/remix#createsessionstorage
export function createUpstashSessionStorage({ cookie }: any) {
  return createSessionStorage({
    cookie,
    async createData(data, expires) {
      // Create a random id - taken from the core `createFileSessionStorage` Remix function.
      const randomBytes = crypto.randomBytes(8);
      const id = Buffer.from(randomBytes).toString("hex");
      // Call Upstash Redis HTTP API. Set expiration according to the cookie `expired property.
      // Note the use of the `expiresToSeconds` that converts date to seconds.
      await fetch(
        `${upstashRedisRestUrl}/set/${id}?EX=${expiresToSeconds(expires)}`,
        {
          method: "post",
          body: JSON.stringify({ data }),
          headers,
        }
      );
      return id;
    },
    async readData(id) {
      const response = await fetch(`${upstashRedisRestUrl}/get/${id}`, {
        headers,
      });
      try {
        const { result } = await response.json();
        return JSON.parse(result).data;
      } catch (error) {
        return null;
      }
    },
    async updateData(id, data, expires) {
      await fetch(
        `${upstashRedisRestUrl}/set/${id}?EX=${expiresToSeconds(expires)}`,
        {
          method: "post",
          body: JSON.stringify({ data }),
          headers,
        }
      );
    },
    async deleteData(id) {
      await fetch(`${upstashRedisRestUrl}/del/${id}`, {
        method: "post",
        headers,
      });
    },
  });
}

今書いたことを説明しましょう:sessions/upstash.server.tsという名前のファイルを作成しました 。このファイルは、createUpstashSessionStorageという名前の関数をエクスポートします 。この関数は、パラメータとしてcookieを取ります。 (これについては後で詳しく説明します)そしてコアRemix createSessionStorageを使用します 新しいセッションプロバイダーを実装するためのファクトリ関数。

関数内にcreateSessionStorageを実装しました 新しいセッションを作成するためのプロトコル(createData )、セッション値を読み取ります(readData )、セッション値を更新します(updateData )そしてセッションを削除します(deleteData

各関数はRESTを使用します Redisデータベースと対話するためのUpstashAPI。

注意事項:
  • 渡されたCookieはcookie expiration dateを保持します js Dateで フォーマット。 expiresToSecondsを使用します これはRedisが期待するものであるため、データを秒に変換する関数。
  • Cookieを設定するときは、有効期限を設定することを忘れないでください。期限切れになると、Redisはそれらのセッションを自動的に削除します。
  • cryptoを使用します 一意のセッションIDを作成します。一意のIDを作成するために他の方法を使用できます。このオプションを選択したのは、コアのcreateFileSessionStorageで使用されているものと同じであるためです。 機能。

ステップ3-createSessionStorageを使用します アプリで

これで、独自のセッションストレージ実装を作成し、その使用方法をデモンストレーションできます。

今後、Upstashに固有のものは何もないことに注意してください。すべてのロジックはsessions/upstash.server.tsにカプセル化されています ファイル。

// sessions.server.ts

import { createCookie } from "remix";
import { createUpstashSessionStorage } from "~/sessions/upstash.server";

// This will set the length of the session.
// For the example we use a very short duration to easily demonstrate its functionally.
const EXPIRATION_DURATION_IN_SECONDS = 10;

const expires = new Date();
expires.setSeconds(expires.getSeconds() + EXPIRATION_DURATION_IN_SECONDS);

const sessionCookie = createCookie("__session", {
  secrets: ["r3m1xr0ck1"],
  sameSite: true,
  expires,
});

const { getSession, commitSession, destroySession } =
  createUpstashSessionStorage({ cookie: sessionCookie });

export { getSession, commitSession, destroySession };

sessions.server.tsという名前のファイルを作成します 上記のコードを貼り付けます。このファイルは、3つの関数getSessionをエクスポートします。 、commitSession およびdestroySession 。これらの機能により、アプリはセッションと対話できます。また、クライアントのセッションへの参照を保存するためのCookieを作成しました。

ビジネスニーズに応じて有効期限を設定します。詳細については、https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies

をお読みください。 リミックスルートでのセッションの使用

Remixを使用すると、ルートごとのセッション使用量を定義できます。次の例では、sessionを使用します routes/index.tsxで 。この例は、セッションAPIの使用方法のみを示しています。セッションを特定のビジネスロジックに接続することは、この投稿の範囲外です。

認証にセッションを使用する方法の例を探している場合は、https://github.com/remix-run/remix/tree/main/examples/remix-auth-form

を参照してください。
// routes/index.tsx

import type { LoaderFunction } from "remix";
import { json, useLoaderData } from "remix";
import { commitSession, getSession } from "~/sessions.server";

export const loader: LoaderFunction = async ({ request }) => {
  // Get the session from the cookie
  const session = await getSession(request.headers.get("Cookie"));
  const myStoredData = session.get("myStoredData");
  // If no session found (was never created or was expired) create a new session.
  if (!myStoredData) {
    session.set("myStoredData", "Some data");
    return json(
      {
        message: "Created new session",
      },
      {
        headers: {
          "Set-Cookie": await commitSession(session),
        },
      }
    );
  }
  // If session was found, present the session info.
  return json({
    message: `Showing Session info: ${myStoredData}`,
  });
};

export default function () {
  const data = useLoaderData();
  return <div>{data.message}</div>;
}

この例は、ユーザーセッションの2つの可能な状態(ユーザーがセッションを持っているか、ユーザーがセッションを持っていない)を処理する方法を示しています。ユーザーがセッションを持っていない場合、アプリのインデックスファイルに移動すると、新しいセッションが作成され、ダミーデータが保存されます。ユーザーが有効な(期限切れではない)セッションを持っている場合、ルートにはセッションのデータが表示されます。

ステップ4-デプロイ

Upstashを使用してセッションを実装したので、選択した展開戦略を自由に選択できます。

Upstash環境変数を設定することを忘れないでください。

付録

createFileSessionStorageの使用 ローカル開発およびcreateUpstashSessionStorage ステージング/制作中

オフラインで開発できるようにしたいと思うかもしれません。ローカルで開発する場合は、createUpstashSessionStorageを置き換えることができます createFileSessionStorageを使用 現在のNODE_ENVを検出する 。

Upstashの実装が機能することをテストした後、sessions/upstash.server.tsを変更します 次のようにファイルします:

このセクションを変更します:

// from sessions/upstash.server.t

const { getSession, commitSession, destroySession } =
  createUpstashSessionStorage({ cookie: sessionCookie });

あり:

// from sessions/upstash.server.ts

const { getSession, commitSession, destroySession } = (process.env.NODE_ENV === "development") ?
createFileSessionStorage({ cookie: sessionCookie, dir: './sessions' });
:  createUpstashSessionStorage({ cookie: sessionCookie });

これで、ローカルで開発する場合、Upstashを呼び出す代わりにローカルファイルシステムを使用します。

結論

この投稿では、UpstashRedisDBを使用してセッションストレージデータをホストする方法を説明しました。 Remix APIは、特定のセッションストレージの実装を非常にうまくカプセル化し、統合を前進させます。この例を試してみたい場合は、https://github.com/remix-run/remix/tree/main/examples/redis-upstash-session

のRemixソースコードで確認できます。

お楽しみください。


  1. TODOアプリをRedisでリミックスする

    この投稿では、RemixとサーバーレスRedis(Upstash)を使用して簡単なTODOアプリを作成します。 Remixはフルスタックのウェブフレームワークであり、ユーザーインターフェースに集中し、ウェブの基本をやり直して、高速で洗練された復元力のあるユーザーエクスペリエンスを提供できます。 リミックスプロジェクトを作成 次のコマンドを実行します: npx create-remix@latest プロジェクトの準備が整いました。それでは、依存関係をインストールして実行しましょう: npm install npm run dev ユーザーインターフェース 簡単なフ

  2. UpstashRedisを使用したNetlifyグラフのグローバルキャッシュ

    昨日、NetlifyはNetlify Graphと呼ばれる新機能を発表しました。私の同僚は最近、写真の同様の欠落部分を強調し、Netlifyは解決に向けて良い一歩を踏み出しました。 基本的に、Netlify Graphは、開発者がWebアプリのGraphQL API呼び出しを構築するのに役立ちます。NetlifyDashboardでGraphQLリクエストを準備した後、シングルクリックでクライアントコードをプロジェクトに挿入できます。 Netlify関数をサードパーティサービスと一緒に使用することには欠点があります。クライアント側のリクエストは、最初にNetlifyバックエンド(関数)に送