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

UpstashRedisをRemixで使用する

Remixは、フルスタックのReactフレームワークであることの意味を新たに取り入れたものであり、既存のWeb標準に焦点を当て、フロントエンドをバックエンドに密接に結び付けています。この緊密な結合は、Reactコンポーネントにデータをロードするのがいかに簡単であるか、またはフォームから送信されたデータを処理する方法を見ると、新鮮な空気の息吹です。

この記事では、UpstashRedisをデータベースとして使用してシンプルな機能フラグ管理システムを作成することでRemixの力を紹介します。

完全なソースコードはここにあります。

セットアップ

npx create-remix@latestを実行すると、まったく新しいRemixアプリを入手できます。 好みの展開環境を選択します。 Vercelを使用しましたが、このチュートリアルでは違いはありません。

Upstash Redisに接続する方法は2つあります。1つは、使い慣れた標準のRedisクライアントライブラリを使用できるTCP接続を使用する方法です。 2つ目は、UpstashのRESTAPIを介したものです。 RemixをデプロイできるCloudflareWorkers環境など、すべてのサーバーレス環境で利用できるため、2番目のオプションを使用します。 Upstashには、実際のRedisコマンドを模倣したパッケージがあり、呼び出す関数を簡単に知ることができます。

ここで、UpstashRedisデータベースに接続するために必要な2つの環境変数を格納する方法が必要です。 Remixには、すぐに使用できる開発環境変数のサポートは付属していませんが、開発依存関係としてdotenvを追加することで実現できます。

npm add --save-dev dotenv

.envで ファイル(.gitignoreに追加する必要があります )UpstashRedisに接続するために必要な2つのenv変数を設定できます。 @upstash/redis パッケージはこれらを自動的に検出するため、コード内で接続する必要はありません。これらの値は、新しいRedisデータベースを作成した後のUpstashダッシュボード内で確認できます。

UPSTASH_REDIS_REST_URL="https://..."
UPSTASH_REDIS_REST_TOKEN="..."

devを更新する必要があります dotenvにenv変数を取得させるスクリプト。他のスクリプトは同じままにすることができます。

{
  "scripts": {
    "dev": "node -r dotenv/config node_modules/.bin/remix dev"
  }
}
機能データの保存

機能フラグは非常に複雑になる可能性があり、ユーザーベースのパーセンテージへの展開計画が特定のユーザーグループに対して有効になりますが、「オン」と「オフ」のように単純にすることもできます。 Redisが提供するハッシュデータ型を使用して機能フラグを保存します。データは以下のJSONのようになり、「1」が有効/オン、「0」が無効/オフになります。

{
  "chart": "1",
  "graph": "0"
}

このデータにアクセスして操作するには、Redisが提供する4つのコマンド/関数を使用します。

  • hgetallは、すべてのキー(機能)と値(有効/無効)を取得します。
  • hsetは特定の機能フラグを有効または無効にします。
  • hdelを使用して特定の機能フラグを削除します。
  • 複数の特定の機能フラグ値を一度に取得するためのhmget。
機能の管理

/featuresにあるページを作成します これは、既存の機能の作成と管理(有効化/無効化/削除)を担当します。 AddFeatureについて詳しく説明します およびFeatureList データの読み込み方法とデータの書き込み方法について話し合うときに行います。

// app/routes/features.tsx
export default function Features() {
  return (
    <div>
      <h1>Features</h1>
      <AddFeature />
      <FeatureList />
    </div>
  );
}
データローダー

データローダーは、loaderという名前のRemixでエクスポートされた関数です。 これはサーバー上で実行され、フックを介してReactコンポーネントで利用できるようになったデータを返します。

機能フラグを作成および管理するページから始めます。この場合、すべての機能を返します。それらはペアの配列として返されます:

[
  ["graph", true],
  ["chart", false]
]

TypeScriptタイプ定義から始めて、loadAllFeaturesという関数が表示されます。 hgetallを使用します @upstash/redisからの関数 。

import { Redis } from "@upstash/redis";

type LoaderData = {
  features: Array<[string, boolean]>;
};

const loadAllFeatures = async () => {
  const redis = Redis.fromEnv();
  const data = await redis.hgetall("features");
  const features: Array<[string, boolean]> = [];

  for (let i = 0; i < data.length; i += 2) {
    features.push([data[i], data[i + 1] === "1"]);
  }

  return features.sort((a, b) => {
    if (a[0] > b[0]) return 1;
    if (a[0] < b[0]) return -1;
    return 0;
  });
};

エクスポートされたloader 関数自体がloadAllFeaturesを呼び出します 関数、Reactコンポーネントに渡される機能を返します。

export const loader: LoaderFunction = async (): Promise<LoaderData> => {
  // You would want to add authentication/authorization here
  const features = await loadAllFeatures();
  return { features };
};

このReactコンポーネントの詳細については後で説明しますが、ローダー関数から返されたデータにアクセスする方法を示すために、useLoaderDataと呼ばれるRemixフックを使用します。 。

const FeatureList = () => {
  const { features } = useLoaderData<LoaderData>();

  return (
    <ul>
      {features.map(([feature, active]) => (
        <li key={feature}>{/* coming soon */}</li>
      ))}
    </ul>
  );
};
フォームアクション

データがどのように読み込まれるかを見てきましたが、この段階では、機能フラグデータベースに実際には機能がありません。ここでフォームアクションが機能します。 actionという名前の関数をエクスポートすることにより、Remixでデータが処理されます。 。 loaderによく似ています 、これはサーバー上で実行され、通常はjsonを返します Reactコンポーネントが別のフックを介してアクセスできるデータ、またはブラウザにredirectするように指示できるデータ 別のページに移動します。

action 以下の関数は、実際には、機能の作成、機能の有効化/無効化、および機能の削除という4つの異なるタイプのアクションを処理します。これはswitchで処理します 次に、適切なRedis関数/コマンドを呼び出すステートメント。

export const action: ActionFunction = async ({ request }) => {
  // You would want to add authentication/authorization here
  const formData = await request.formData();
  const feature = formData.get("feature") as string;
  const action = formData.get("_action") as string;

  if (!feature || feature.length === 0) {
    // This isn't currently displayed in our component
    return json({ error: "Please provide a feature" });
  }

  switch (action) {
    case "create":
    case "enable":
      await redis.hset("features", { [feature]: 1 });
      break;
    case "disable":
      await redis.hset("features", { [feature]: 0 });
      break;
    case "delete":
      await redis.hdel("features", feature);
      break;
  }

  return redirect("/features");
};

成功すると、ユーザーが現在表示しているのと同じページにリダイレクトすることに気付くでしょう。これは基本的にページのリロードをトリガーし、loaderを呼び出します 機能し、ユーザーに表示される内容を更新します。

新しい機能フラグを追加するには、AddFeature コンポーネントはRemixFormを使用します 上記のアクション関数にデータを送信するコンポーネント。 post経由で送信するように指定しました メソッドとreplaceも提供しました 機能フラグを作成するたびにブラウザの履歴に新しいページが追加されないようにするための小道具。

const AddFeature = () => {
  return (
    <Form method="post" replace>
      <input type="hidden" name="_action" value="create" />
      <input type="text" name="feature" required placeholder="name" />
      <button type="submit">Add</button>
    </Form>
  );
};

機能が作成されたら、管理できるように現在のすべての機能フラグを表示する必要があります。各機能フラグには、実際には2つの形式が表示されます。1つは機能フラグを有効/無効にするためのもので、もう1つは機能フラグを削除するためのものです。

_actionという2つの非表示フィールドがあることに注意してください。 action functionは、機能に対して何をしようとしているのか、およびfeatureを認識しています。 変更するフラグ名を送信します。

const FeatureList = () => {
  const { features } = useLoaderData<LoaderData>();

  return (
    <ul>
      {features.map(([feature, active]) => (
        <li key={feature}>
          <Form method="post" replace>
            <input
              type="hidden"
              name="_action"
              value={active ? "disable" : "enable"}
            />
            <input type="hidden" name="feature" value={feature} />
            <button type="submit" className="btn-naked">
              {active ? "💪" : "🦾"}
            </button>
          </Form>

          <span>{feature}</span>

          <Form method="post" replace>
            <input type="hidden" name="_action" value="delete" />
            <input type="hidden" name="feature" value={feature} />
            <button type="submit">Delete</button>
          </Form>
        </li>
      ))}
    </ul>
  );
};
機能の使用

Upstash Redisデータベースには機能フラグがありますが、これらのフラグに基づいてアプリの機能のオンとオフを切り替えないのは良いことです。ローダー関数を使用して、hmgetを使用してデータベースから特定の機能をロードします 、次にデータを少し操作して適切な構造にします。

["chart", "graph", "fake"]をロードする場合 フラグ、Redisは["1", "0", null]を返します ...フラグが存在しない場合、その値はnullになることに注意してください。 、fakeを含めて表示したかった フラグ。

type LoaderData = {
  features: Record<string, boolean>;
};

const loadFeatures = async (keys: Array<string>) => {
  const data = await redis.hmget("features", ...keys);

  const features = keys.reduce<Record<string, boolean>>((acc, key, index) => {
    acc[key] = data[index] === "1";
    return acc;
  }, {});

  return features;
};

export const loader: LoaderFunction = async (): Promise<LoaderData> => {
  const features = await loadFeatures(["chart", "graph"]);
  return { features };
};

これで、RemixのuseLoaderDataを使用して、コンポーネントにロードされたデータにアクセスできるようになりました。 針。次に、フラグが現在有効か無効かを考慮して、Webサイトの機能をどのように変更するかを選択します。

export default function Index() {
  const { features } = useLoaderData<LoaderData>();

  return (
    <div>
      <h1>Dashboard</h1>
      {features.chart ? <h2>Chart</h2> : <h2>No Chart</h2>}
      {features.graph ? <h2>Graph</h2> : <h2>No Graph</h2>}
    </div>
  );
}
結論

この記事では、Upstash Redisを使用して、データローダーとフォームアクションサーバー側の機能を利用して、Remixでシンプルな機能フラグシステムを作成する方法を説明しました。これらにより、特定のページのバックエンドとフロントエンドを緊密に結合し、個別のGraphQL APIを設定したり、フロントエンドで標準のフォーム送信イベントをオーバーライドしたりすることなく、すばやく反復することができます。これまで見てきたように、リミックスは、フォームがデータを送信する方法に関するWeb標準に依存しています。


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

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

  2. CloudflareワーカーとのRedis@Edge

    エッジでのコンピューティングは、近年最もエキサイティングな機能の1つです。 CDNを使用すると、ファイルをユーザーに近づけることができます。エッジコンピューティングを使用すると、アプリケーションをユーザーの近くで実行できます。これは、開発者がグローバルに分散されたパフォーマンスの高いアプリケーションを構築するのに役立ちます。 Cloudflare Workersは、現在この分野の主要製品です。コールドスタートのないサーバーレス処理環境を提供します。 Cloudflareのグローバルネットワークを活用して、アプリケーションのレイテンシーを最小限に抑えます。関数はJavascript、Rust、