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

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1

この投稿では、データを保存するためのFlutter、Serverless Framework、Upstash、Redisを使用してサーバーレスモバイルアプリケーションを構築します。

Upstashとは?

Upstashは、Redis用のサーバーレスデータベースです。 Upstashを使用すると、リクエストごとに支払います。これは、データベースが使用されていないときに課金されないことを意味します。

Upstashはデータベースを構成および管理します。これは、DynamoDBやFaunaなどの他のデータベースの強力な代替手段であり、

などの利点があります。
  • 低レイテンシ
  • REDISAPIと同じように使いやすさ。

これは、Upstashを代替のクラウドベースのソリューションと比較した詳細なドキュメントであり、次のプロジェクトでUpstashを選択する理由を明確に示しています。

この記事をチェックして、利用可能なすべてのサーバーレスデータベースを比較することもできます

Upstashを使用すると、

  • 無料で始めて、使用した分だけ支払います
  • 高速で耐久性のあるストレージを備えています
  • グローバルデータベースとエッジキャッシングにより、世界中のどこからでも低レイテンシでデータベースにアクセスできます。

今すぐ無料でUpstashを始めましょう

Upstashでアプリケーションを効果的に構築するには、Redisを理解する必要があります。そのため、Redisを簡単に紹介し、Upstashアプリ内でどのように使用するかを確認します。

より詳細で詳細な情報が必要な場合は、Redisの公式Webサイトをお勧めします

Redisは、オープンソース(BSDライセンス)のメモリ内データ構造ストアであり、データベース、キャッシュ、およびメッセージブローカーとして使用されます。

などの大量のデータ構造をサポートします
  • 文字列
  • ハッシュ
  • リスト
  • セット
  • 範囲クエリを使用して並べ替えられたセット
  • ビットマップ
  • ハイパーログログ
  • 地理空間インデックス

コマンドを使用してRedisデータベースを操作し、キー値形式でデータを保存します。キーは文字列と値、Redisでサポートされている任意のデータ構造にすることができます。

たとえば、Redisコマンドの SETを使用できます 私の名前の値をそのように保存する

SET surname Rosius

ここで、 surname が鍵であり、Rosiusが価値です。

Redisで注意すべき非常に重要なことの1つは、データを簡単に取得できる方法で常に保存することです。

Redisで値でキーを直接検索する方法はありません。

Redisのデータは永続的に保存されます。したがって、キー surnameに保存されているデータを取得できます。 そのように

GET surname

'Rosius'の結果

キーsurnameに保存されている値を削除することもできます そのように

DEL surname

投稿のいいねをインクリメントしたいとします。 INCR を使用して、これを簡単に行う方法は次のとおりです。 アトミックなコマンド。

SET likes 10
INCR likes => 11
INCR likes => 12
INCR likes => 13

まず、いいねの初期値を10に設定し、次にいいねの値をアトミックにインクリメントします。これで、 likesもインクリメントできると思うでしょう。 このように。

x = GET likes
x = x + 1
SET likes x

アプリケーションを使用しているのがあなただけである限り、これはまったく問題ありません。これは決して正しいことではありません。

2人以上が同じようにインクリメントすると、上記のプロセス(GET、Increment、SET)はアトミックではなくなります。したがって

x = GET likes (yields 10)
y = GET likes (yields 10)
x = x + 1 (x is now 11)
y = y + 1 (y is now 11)
SET likes x (likes is now 11)
SET likes y (likes is now 11

上記のコードから、ユーザー1は10のlikesの値を取得し、それを変数xに格納します。同時に、ユーザー2は10のlikesの同じ値を取得し、それを変数に格納します。 y。

ユーザー1はlikes(x)の値に1を加算し、新しい値を設定します。これは現在11です。

ユーザー2も同じことをします。

したがって、いいねの値は11です。

しかし、それは本当に正しいのでしょうか?いいねは2人の異なるユーザーによって2回インクリメントされていることを忘れないでください。

Likesの値は11ではなく12でなければなりませんでした。そのため、Redisは INCRを提供しています。 コマンド。これはアトミックであり、このような問題を解決します。

ハッシュデータ型

Redisハッシュは、他のプログラミング言語のハッシュと同等です。基本的に、値に関連付けられたフィールドのコレクションで構成されています。

たとえば、ユーザープロファイル情報をハッシュに保存する方法は次のとおりです。

HMSET userProfile:100034  "userId" 100034 "username" "Rosius Ndimofor"
            "firstName" "Rosius" "lastName" "Ndimofor" "profilePic" "rosius.jpeg"

まず、ハッシュのキーは userProfile:100034です。 、次に key value すべてのペア。例: "userId" はキーで、100034'は値です。 を使用して、名などの特定のユーザープロファイル情報を取得できます。 HGETコマンドと userId`はそうです。

userId = 100034
HGET userProfile:{userId} firstName

または、 GETALL を使用して、特定のユーザーのすべてのユーザープロファイル情報を取得できます。 そのようなコマンド

userId = 100034
HGETALL userProfile:{userId}
リストデータ型

以前、Redisでは、データを取得する予定の方法でデータを保存することが非常に重要であると述べました。

プラットフォームにすべてのユーザーを参加させたい場合はどうなりますか?

ユーザープロファイル情報を保存するためにハッシュデータ構造を使用しました。次に、システム上のすべてのユーザーを取得する必要があります。

これを実現する最も簡単な方法は、次のようにコマンドLPUSH(左プッシュの略)を使用して、すべてのユーザーのuserIdをリストに保存することです。

LPUSH "users" userId

リストからすべてのユーザーを取得するには、コマンド LRANGEを使用します そのように

LRANGE  "users" 0  -1

これらは、アプリケーションで使用するコマンドのほんの一部です。ただし、Redisの公式サイトにアクセスして、残りのコマンドを確認し、それらの使用方法を学ぶことをお勧めします。

では、フルスタックアプリケーションはどのように機能するのでしょうか?

よろしくお願いします。それで、今日は、CRUDAPIを作成することから始めます。これがユースケースです。

2つのエンティティがあります。 ユーザー および投稿

彼らは1対多の関係を共有しています。したがって、1人のユーザーが複数の投稿を持つことができ、1つの投稿は1人のユーザーにのみ属することができます。

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1

ユーザーは許可されます

  • アカウントを作成します。認証なし。 AWSCognitoまたはAuth0を使用して認証を追加できます。
  • アカウントを更新する
  • アカウントを取得する
  • 投稿を作成する
  • 投稿を更新する
  • 投稿のように
  • すべての投稿のリストを取得する

これがソリューションのアーキテクチャビューです

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1 では始めましょう。

Upstashアカウントを作成する

ここで無料のUpstashアカウントを作成してくださいUpstashログイン。

アカウントを作成したら、Upstashデータベースを作成します。

無料利用枠に作成できるデータベースは1つだけです。

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1 Redisデータベースエンドポイントをメモします。 rediss://:2c9bb162c2444bf7ab689640bb2ead23@gusc1-smashing-bee-30249.upstash.io:00049

サーバーレスプロジェクトの作成 前提条件

続行する前に、これらの依存関係をインストールしてください

  • AWS CLI

  • NodeJS

  • サーバーレスCLI

    以下のコマンドを使用し、プロンプトに従って、新しいサーバーレスプロジェクトを作成します。

serverless

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1

nodejs HTTP APIを選択し、プロジェクトに名前を付けて、 enterを押します。 。

これが私のサーバーレスプロジェクトの初期構造です。

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1

そのフォルダ内で、コマンド

を使用して新しいノードプロジェクトを初期化します。
npm init

次に、

を使用してredisクライアントをインストールします
npm install ioredis

また、普遍的に一意の識別子(uuid)依存関係をインストールします。このプロジェクトではこれを幅広く使用します。

npm install uuid

次に、Redisデータベースエンドポイントを serverless.ymlの環境変数として追加します そのようなファイル。

provider:
  name: aws
  region: us-east-1
  stage: dev
  runtime: nodejs12.x
  lambdaHashingVersion: "20201221"
  environment:
    REDIS_CLIENT: "rediss://:2c9bb162c2444bf7ab689640bb2ead23@gusc1-smashing-wasp-30249.upstash.io:30249"

次に、プロジェクト内に usersという名前の2つのフォルダーを作成します およびposts 。これらのフォルダーは両方とも、それぞれのユースケースのラムダ関数を保持します。

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1

APIエンポイントの作成を始めましょう

ユーザーの作成

ユーザーが自分でアカウントを作成できるようにする必要があります。

認証なし。彼らがしなければならないのは彼らを提出することだけです

  • ユーザー名
  • 名前
  • プロフィール写真

userでファイルを作成します create.jsというフォルダ 。

ファイルの先頭で、 serverless.yml に環境変数として保存したredisデータベースのURLを使用して、redisクライアントをインポートしてインスタンス化します。 ファイル。

"use strict";
const uuid = require("uuid");
var Redis = require("ioredis");
if (typeof client === "undefined") {
  var client = new Redis(process.env.REDIS_CLIENT);
}

また、uuid依存関係をインポートします。これは、uuid依存関係を使用してユーザーの一意のIDを作成するためです。

まず、ユーザープロファイルを保存するためのデータ構造が必要です 情報、およびuserIdのを保存するための別のデータ構造 アプリケーション内のすべてのユーザーの。

ハッシュとリストのデータ型を覚えていますか?

データ型をハッシュして、ユーザープロファイル情報を保存します。データ型キーuserItem:$ {userId}に注意してください

await client.hmset(
  `userItem:${userId}`,
  "userId",
  userId,
  username,
  data.username,
  firstName,
  data.firstName,
  lastName,
  data.lastName,
  profilePic,
  data.profilePic,
  "timestamp",
  timestamp
);

次に、作成した userIdを保存します usersというリストに

await client.lpush("users", userId);

お気づきの方は、2つのオペレーションを送信する必要があります。次々に送信することは可能ですが、それは最適ではありません。

Upstashは、パイプラインと呼ばれる機能を通じてバッチ操作をサポートします 。

したがって、単一のコマンドを送信して応答を待つ代わりに、複数のコマンドを送信することができ、コマンドを送信したのと同じ方法で応答が返されます。

パイプラインを使用した後の操作は次のようになります

client.pipeline(
  await client.hmset(
    `userItem:${userId}`,
    "userId",
    userId,
    username,
    data.username,
    firstName,
    data.firstName,
    lastName,
    data.lastName,
    profilePic,
    data.profilePic,
    "timestamp",
    timestamp
  ),
  await client.lpush("users", userId)
);

次に、すべてのユーザーの保存プロファイル情報を取得し、 api-gatewayを介して応答として返すことができます。 。

//get and display saved user item
const userItem = await client.hgetall(`userItem:${userId}`);

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1

serverless.ymlを更新することを忘れないでください このエンドポイントを反映します。

functions:
  createUser:
    handler: user/create.createUser
    events:
      - http:
          path: /user
          method: post

関数の名前はcreateUserです。 、および create.jsというファイルにあります これはuserというフォルダ内にあります 。したがって、ハンドラー user / create.createUser

パス/userに注意してください

createUser 関数はpostを使用します httpメソッド。

users / create.jsの完全なコードは次のとおりです ファイル

"use strict";
const uuid = require("uuid");
var Redis = require("ioredis");
const username = "username";
const firstName = "firstName";
const lastName = "lastName";
const profilePic = "profilePic";

if (typeof client === "undefined") {
  var client = new Redis(process.env.REDIS_CLIENT);
}

/**
 *
 * @param {username,firstName,lastName,profilePic} event
 * @returns
 */
module.exports.createUser = async (event) => {
  const timestamp = new Date().getTime();

  const data = JSON.parse(event.body);
  if (data == null) {
    return {
      statusCode: 400,
      body: JSON.stringify(
        {
          message: "Couldn't create the user item",
        },
        null,
        2
      ),
    };
  }

  const userId = uuid.v1();
  console.log(`userId is ${userId}`);
  // here, we use a pipeline to perform multiple requests
  // Firstly, we save the user details to a hash dataset with key (`userItem:${userId}`)
  //
  client.pipeline(
    await client.hmset(
      `userItem:${userId}`,
      "userId",
      userId,
      username,
      data.username,
      firstName,
      data.firstName,
      lastName,
      data.lastName,
      profilePic,
      data.profilePic,
      "timestamp",
      timestamp
    ),
    await client.lpush("users", userId)
  );

  //get and display saved user item
  const userItem = await client.hgetall(`userItem:${userId}`);

  console.log(userItem);

  return {
    statusCode: 200,
    body: JSON.stringify(userItem),
  };
};
ユーザーの更新

ユーザーは自分のプロファイルを時々更新したいと思っています。したがって、ユーザー更新エンドポイントを提供するのが適切です。

この操作に必要なコマンドは、 HMSETだけです。 コマンドとuserId

Redisのドキュメントから、 HMSETの正確な方法は次のとおりです。 コマンドは機能します。

指定されたフィールドを、キーに格納されているハッシュのそれぞれの値に設定します。このコマンドは、ハッシュにすでに存在する指定されたフィールドを上書きします。

コードは次のようになります。

"use strict";
const uuid = require("uuid");
var Redis = require("ioredis");
const username = "username";
const firstName = "firstName";
const lastName = "lastName";

if (typeof client === "undefined") {
  var client = new Redis(process.env.REDIS_CLIENT);
}

/**
 *
 * @param {username,firstName,lastName,age,profilePic} event
 * @returns
 */
module.exports.updateUser = async (event) => {
  const timestamp = new Date().getTime();
  const userId = event.pathParameters.id;
  const data = JSON.parse(event.body);
  if (userId == null) {
    return {
      statusCode: 400,
      body: JSON.stringify(
        {
          message: "Couldn't update the user item",
        },
        null,
        2
      ),
    };
  }

  //get

  await client.hmset(
    `userItem:${userId}`,
    username,
    data.username,
    firstName,
    data.firstName,
    lastName,
    data.lastName
  );

  //get and display saved user item
  const userItem = await client.hgetall(`userItem:${userId}`);

  console.log(userItem);

  return {
    statusCode: 200,
    body: JSON.stringify(userItem),
  };
};

次に、 serverless.ymlで ファイル、関数の下に追加...

updateUser:
  handler: user/update.updateUser
  events:
    - http:
        path: /user/{id}
        method: put

userIdを渡します パスパラメータとして/user / {id}

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1

ユーザーを取得

HGETALLを使用する コマンドとハッシュキーを使用すると、特定のユーザーのユーザープロファイル情報を取得できます。

HGETも使用できることに注意してください firstNameやlastNameなどのユーザー固有の情報を取得するコマンド。

コードを見てみましょう

userでファイルを作成します get.jsというフォルダ

"use strict";
var Redis = require("ioredis");

if (typeof client === "undefined") {
  var client = new Redis(process.env.REDIS_CLIENT);
}

module.exports.getUserById = async (event) => {
  const userId = event.pathParameters.id;

  if (userId == null) {
    return {
      statusCode: 400,
      body: JSON.stringify(
        {
          message: "Couldn't get the user item",
        },
        null,
        2
      ),
    };
  }

  console.log(`userId is ${userId}`);

  //get and display saved user item
  const userItem = await client.hgetall(`userItem:${userId}`);

  console.log(userItem);

  return {
    statusCode: 200,
    body: JSON.stringify(userItem),
  };
};

次に、 serverless.ymlで ファイル、

getUser:
  handler: user/get.getUserById
  events:
    - http:
        path: /user/{id}
        method: get

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1

ユーザーの一覧表示

ユーザーを作成するためのハンドラーを作成したときは、プッシュしたままにしたことを思い出してください( LPUSH )userIdを usersに挿入します リスト。

ここで、コマンド LRANGE を使用して、これらすべてのIDを取得する必要があります。 。

注:投稿のリストが非常に大きくなり始めた場合、LRANGEはあまり効率的ではありません。また、Redisリストはリンクリストに基づいているため、リストの中央にある要素にアクセスする必要があります。システムが数百万のアイテムの深いページネーション用に設計されている場合は、代わりに並べ替えられたセットを使用することをお勧めします。

すべてのuserIdを取得したら、各 idをループできます。 HGETALLを使用してユーザープロファイル情報を取得します 。

これがコードでどのように見えるか見てみましょう。

"use strict";
var Redis = require("ioredis");

if (typeof client === "undefined") {
  var client = new Redis(process.env.REDIS_CLIENT);
}

module.exports.getAllUsers = async (event) => {
  let users = [];
  let response = await client.lrange("users", 0, -1);

  async function getAllUsers() {
    let users = [];

    await Promise.all(
      response.map(async (userId) => {
        const item = await client.hgetall(`userItem:${userId}`);
        users.push(item);
        console.log(users);
      })
    );

    return users;
  }
  users = await getAllUsers();

  return {
    statusCode: 200,
    body: JSON.stringify(users),
  };
};

次に、 serverless.ymlの場合

listUsers:
  handler: user/list.getAllUsers
  events:
    - http:
        path: /users
        method: get

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1

ユーザーは以上です エンドポイント。まだ行っていない場合は、先に進んでアプリをデプロイできます。

sls deploy
投稿

ユーザーがアカウントを作成したら、許可する必要があります

  • 投稿を作成する
  • IDで投稿を取得
  • 投稿のリストを取得する
  • 投稿と同じまたは異なる(投稿に反応する)

始めましょう。

投稿を作成

投稿を作成するために必要なパラメータは次のとおりです

  • userId
  • postId(UUIDによって自動生成)
  • postText
  • postImage
  • createdOn

3つのステップが含まれます。

  1. HMSETコマンドを使用して、投稿の詳細をハッシュキーに設定します postItem:$ {postId}
  2. LPUSHコマンドを使用して、postIdを投稿のリストに追加します 。
  3. LPUSHコマンドを使用して、postIdを userPost:$ {userId}のリストに追加します 。

パイプラインを使用して、このタスクを時系列で実行します。

postにファイルを作成します create.jsというフォルダ 次のコードを追加します。

"use strict";
const uuid = require("uuid");
var Redis = require("ioredis");

if (typeof client === "undefined") {
  var client = new Redis(process.env.REDIS_CLIENT);
}

/**
 *
 * @param {userId,postId,postText,postImage,createdOn} event
 * @returns
 */
module.exports.createPost = async (event) => {
  const timestamp = new Date().getTime();
  const postId = uuid.v1();
  const data = JSON.parse(event.body);
  if (data == null) {
    return {
      statusCode: 400,
      body: JSON.stringify(
        {
          message: "Couldn't create the Post item",
        },
        null,
        2
      ),
    };
  }

  console.log(`postId is ${postId}`);

  client.pipeline(
    await client.hmset(
      `postItem:${postId}`,
      "id",
      postId,
      "userId",
      data.userId,
      "postText",
      data.postText,
      "postImage",
      data.postImage,
      "createdOn",
      timestamp
    ),
    await client.lpush("posts", postId),
    await client.lpush(`userPost:${data.userId}`, postId)
  );

  //get and display saved post item
  const postItem = await client.hgetall(`postItem:${postId}`);

  console.log(postItem);

  return {
    statusCode: 200,
    body: JSON.stringify(postItem),
  };
};

次に、 serverless.ymlの関数の下にあります 、追加

createPost:
  handler: post/create.createPost
  events:
    - http:
        path: /post
        method: post

展開してテストします。

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1

IDで投稿を取得

Idで投稿を取得するときは、投稿管理者の詳細と、投稿のこれまでの反応(いいね)の数を取得して添付します。

投稿の好き嫌いについてはまだ検討していませんが、しばらくお待ちください。 get.jsというファイルを作成します。 投稿フォルダに保存して

"use strict";
var Redis = require("ioredis");

if (typeof client === "undefined") {
  var client = new Redis(process.env.REDIS_CLIENT);
}

module.exports.getPostById = async (event) => {
  const postId = event.pathParameters.id;
  if (postId == null) {
    return {
      statusCode: 400,
      body: JSON.stringify(
        {
          message: "Couldn't get the post item",
        },
        null,
        2
      ),
    };
  }

  console.log(`postId is ${postId}`);

  //get and display saved post item
  const postItem = await client.hgetall(`postItem:${postId}`);
  const userItem = await client.hgetall(`userItem:${postItem.userId}`);
  const postReactionsCount = await client.get(`postReactionsCount:${postId}`);
  postItem["postAdmin"] = userItem;
  postItem["reactionCount"] =
    postReactionsCount == null ? 0 : postReactionsCount;
  console.log(postItem);
  console.log(userItem);

  return {
    statusCode: 200,
    body: JSON.stringify(postItem),
  };
};

上記のコードから、最初に、 hgetallを使用して特定の投稿のすべての投稿の詳細を取得します コマンドとキーpostItem:$ {postId}

次に、投稿オブジェクトには投稿を行ったユーザー(投稿管理者)のuserIdがあるため、 userItem:$ {postItem.userId}を使用します。 そのユーザーのユーザー詳細を取得します。

これは、上記のユーザーエンドポイントの作成で使用したものとまったく同じキーであったことに注意してください。

第三に、 getを使用してpostReactionCountを取得します コマンドとキーpostReactionsCount:$ {postId} 後でpostReactionsCountを保存するために使用します。

展開とテスト

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1

投稿に反応する

これは、アプリケーション全体の中で最も興味深いエンドポイントです。書くのは楽しかったです。

ユーザーは、投稿を高く評価したり、異なったりすることができます。これで、ユーザーが「いいね」ボタンをクリックすると、最初にこのユーザーが以前に投稿を高く評価したことがあるかどうかを確認します。

はいの場合、投稿とは異なります。それ以外の場合は、投稿が気に入っています。

分かりますか?

InstagramやTwitterのように。

react_to_post.jsという名前の投稿フォルダーにファイルを作成します

エンドポイントはuserIdを取ります およびpostId パスパラメータとして。

新しいコマンドを見てみましょう。ソートされたセット。並べ替えられたセットを使用して、投稿を高く評価しているユーザーのuserIdと、投稿を高く評価したときのタイムスタンプを追加します。

zadd(`postReactions:${postId}`, timestamp, data.userId)

キーはpostReactions:$ {postId}です 。

並べ替えられたセットはZで始まります。Redisのドキュメントから、 zadd

キーに保存されているソート済みセットに、指定されたスコアを持つ指定されたすべてのメンバーを追加します。複数のスコア/メンバーのペアを指定することが可能です。指定されたメンバーがすでに並べ替えられたセットのメンバーである場合、スコアが更新され、要素が正しい位置に再挿入されて、正しい順序になります。

次のステップは、を使用してpostReactionsCount:${postId}をインクリメントすることです。 incr`コマンド。

ポストリアクションカウントを取得するために、Get PostbyIdエンドポイントで上記のキーを使用したことを思い出してください。

incr(`postReactionsCount:${postId}`),

最後に、ユーザーの投稿の反応の詳細をハッシュに保存します

hmset(`userPostReactions:${data.userId}`,
                "postId", postId,
                "userId", data.userId,
                "timestamp", timestamp
            ),

これらすべてに基づいて、利用可能なアクセスパターンは次のとおりです。

  • 反応後のカウントを取得できます。
  • 投稿に反応したすべてのユーザーを昇順または降順で取得できます
  • ユーザーが反応したすべての投稿を取得できます。

前述しましたが、ユーザーが以前に投稿を高く評価したかどうかを確認する必要があります。はいの場合、その投稿とは異なります。それ以外の場合は投稿が好きです

zscoreを使用します このためのコマンド。

キーでソートされたセットのメンバーのスコアを返します。ソートされたセットにメンバーが存在しない場合、またはキーが存在しない場合は、nilが返されます。

zscore(`postReactions:${postId}`, data.userId);

zscoreの場合 nullの場合、ユーザーはそれを気に入らなかった。それ以外の場合、ユーザーはそれを気に入っています。

完全なコードは次のようになります

"use strict";
const uuid = require("uuid");
var Redis = require("ioredis");

if (typeof client === "undefined") {
  var client = new Redis(process.env.REDIS_CLIENT);
}

/**
 *
 * @param {userId,postId,postText,postImage,createdOn} event
 * @returns
 */
module.exports.reactToPost = async (event) => {
  const timestamp = new Date().getTime();

  const data = JSON.parse(event.body);
  const postId = event.pathParameters.id;

  if (data == null || postId == null) {
    return {
      statusCode: 400,
      body: JSON.stringify(
        {
          message: "Couldn't react to the Post",
        },
        null,
        2
      ),
    };
  }

  console.log(`postId is ${postId}`);
  console.log(`userId is ${data.userId}`);
  // first check if user has already liked the post
  const hasUserReacted = await client.zscore(
    `postReactions:${postId}`,
    data.userId
  );
  if (hasUserReacted == null) {
    //user hasn't reacted.
    client.pipeline(
      await client.incr(`postReactionsCount:${postId}`),
      await client.zadd(`postReactions:${postId}`, timestamp, data.userId),
      await client.hmset(
        `userPostReactions:${data.userId}`,
        "postId",
        postId,
        "userId",
        data.userId,
        "timestamp",
        timestamp
      )
    );
  } else {
    //user already reacted, so unreact
    client.pipeline(
      await client.decr(`postReactionsCount:${postId}`),
      await client.zrem(`postReactions:${postId}`, data.userId),
      await client.hdel(
        `userPostReactions:${data.userId}`,
        "postId",
        postId,
        "userId",
        data.userId,
        "timestamp",
        timestamp
      )
    );
  }

  //return the post reaction count
  const postReactionsCount = await client.get(`postReactionsCount:${postId}`);

  console.log(postReactionsCount);

  return {
    statusCode: 200,
    body: JSON.stringify({
      postReactionCount: parseInt(postReactionsCount),
    }),
  };
};

次に、 serverless.yml

reactToPosts:
  handler: post/react_to_post.reactToPost
  events:
    - http:
        path: /post/{id}/react
        method: post

展開してテストします。

Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート1

APIテスター(私はPostManを使用)の送信ボタンを複数回押して、「postReactionCount」が0と1の間でどのように切り替わるかを確認します。

UserIdを変更して、もう一度確認してください。

このAPIに追加できるアクセスパターンと修正は他にもたくさんあります。

これを拡張して詳細を学ぶために挑戦してみませんか。

完全なソースコードへのリンクは次のとおりです

私は、Redisのそれほど急ではない学習曲線と、データを取得する方法でデータを保存できるという事実を絶対に気に入っています。

アプリの開発を開始する前に、アクセスパターンを常に把握してください。

この作品を書くのはとても楽しかったです。あなたが1つか2つのことを学んだことを願っています。

どこかで間違えましたか?あなたのような超サイヤ人は私に知らせることを躊躇しません。

次の記事では、このAPIを使用するFlutterアプリを作成します。しばらくお待ちください。

HappyCodingComrade✌🏿

リファレンス
  • ドキュメントのアップスタッシュ
  • Redis
  • フラッター
  • インターネットからのデータの取得

  1. Nuxt3とサーバーレスRedisの使用を開始する

    はじめに アプリケーションの使用状況を追跡したり、リソースの使用率を制限したり、キャッシュからデータをフェッチしてアプリのパフォーマンスを向上させたりする必要がある場合は、Redisがこれらの要件に対する答えであることがわかります。 Redisは、メモリ内のKey-Valueデータベースです。これはオープンソースであり、RemoteDictionaryServerの略です。 この記事では、Upstash、Redisデータベース、およびVueSSRフレームワークの最近のベータリリースであるNuxt3について説明します。これは、Redisデータベースについて説明する初心者向けの記事で、 Nux

  2. Flutter、サーバーレスフレームワーク、Upstash(REDIS)を備えたフルスタックサーバーレスアプリ-パート2

    このチュートリアルシリーズのパート2へようこそ。最初のパートでは、Upstash、Serverless Framework、およびRedisを使用してRESTAPIを構築する方法を説明しました。 このパートでは、Flutterを使用してモバイルアプリケーションを構築し、RESTAPIエンドポイントを使用します。 始めましょう🙃 まず、フラッターをコンピューターにインストールして実行する必要があります フラッター IDEで新しいフラッタープロジェクトを作成し、任意の名前を付けます。 pubspec.yamlを開きます flutterプロジェクトのルートディレクトリにあるファイルを