Computer >> कंप्यूटर >  >> प्रोग्रामिंग >> Redis

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1

इस पोस्ट में, हम डेटा स्टोर करने के लिए फ़्लटर, सर्वरलेस फ्रेमवर्क, अपस्टैश और रेडिस के साथ एक सर्वर रहित मोबाइल एप्लिकेशन का निर्माण करेंगे।

अपस्टैश क्या है?

Upstash Redis के लिए एक सर्वर रहित डेटाबेस है। Upstash के साथ, आप प्रति-अनुरोध का भुगतान करते हैं। इसका मतलब है कि जब डेटाबेस उपयोग में नहीं होता है तो आपसे शुल्क नहीं लिया जाता है।

Upstash आपके लिए डेटाबेस को कॉन्फ़िगर और प्रबंधित करता है। यह डायनेमोडीबी और फॉना जैसे अन्य डेटाबेस के लिए एक मजबूत विकल्प है, जैसे कि

  • कम विलंबता
  • उपयोग में आसानी, बिल्कुल रेडिस एपीआई की तरह।

वैकल्पिक क्लाउड-आधारित समाधानों के साथ अपस्टैश की तुलना करने वाला एक विस्तृत दस्तावेज़ यहां दिया गया है, जो आपको स्पष्ट कारण देता है कि आपको इसे अपने अगले प्रोजेक्ट के लिए क्यों चुनना चाहिए।

आप सभी उपलब्ध सर्वर रहित डेटाबेस की तुलना करते हुए इस लेख को भी देख सकते हैं

Upstash के साथ,

  • आप नि:शुल्क शुरुआत करते हैं और केवल उसी के लिए भुगतान करते हैं जिसका आप उपयोग करते हैं
  • इसमें तेज़, टिकाऊ स्टोरेज है
  • आप वैश्विक डेटाबेस और एज कैशिंग के कारण कम विलंबता के साथ दुनिया भर में कहीं से भी अपने डेटाबेस तक पहुंच सकते हैं।

Upstash पर आज ही निःशुल्क प्रारंभ करें

Upstash पर प्रभावी रूप से एप्लिकेशन बनाने के लिए, आपको Redis को समझना होगा। इसलिए यह बिल्कुल सही है कि हम Redis का संक्षिप्त परिचय देते हैं और देखते हैं कि हम अपने Upstash ऐप में इसका उपयोग कैसे करेंगे।

यदि आप कुछ अधिक विस्तृत और गहराई से पसंद करते हैं, तो मैं आधिकारिक रेडिस वेबसाइट की अनुशंसा करता हूं

रेडिस एक ओपन सोर्स (बीएसडी लाइसेंस प्राप्त), इन-मेमोरी डेटा स्ट्रक्चर स्टोर है, जिसका उपयोग डेटाबेस, कैशे और मैसेज ब्रोकर के रूप में किया जाता है।

यह एक टन डेटा संरचनाओं का समर्थन करता है जैसे कि

  • स्ट्रिंग्स
  • हैश
  • सूचियां
  • सेट
  • श्रेणी प्रश्नों के साथ क्रमबद्ध सेट
  • बिटमैप
  • हाइपरलॉग्स
  • भू-स्थानिक अनुक्रमणिका

आप कमांड का उपयोग करके रेडिस डेटाबेस के साथ इंटरैक्ट करते हैं और डेटा को एक कुंजी मान प्रारूप में सहेजते हैं, जहां कुंजी एक स्ट्रिंग और मान हो सकती है, रेडिस द्वारा समर्थित कोई भी डेटा संरचना।

उदाहरण के लिए, मैं रेडिस कमांड का उपयोग कर सकता हूं SET मेरे उपनाम के मूल्य को इस तरह संग्रहीत करने के लिए

SET surname Rosius

जहां उपनाम कुंजी है और रोसियस मान है।

Redis के साथ ध्यान देने योग्य एक बहुत ही महत्वपूर्ण बात है, अपने डेटा को हमेशा इस तरह से संग्रहित करें कि आप उसे आसानी से प्राप्त कर सकें।

रेडिस में मूल्य के आधार पर कुंजी खोजने का कोई सीधा तरीका नहीं है।

रेडिस में डेटा स्थायी रूप से संग्रहीत होता है। इसलिए मैं कुंजी उपनाम . पर संग्रहीत डेटा पुनर्प्राप्त कर सकता हूं ऐसा ही

GET surname

'रोसियस' के परिणाम

हम कुंजी उपनाम . पर संग्रहीत मान को भी हटा सकते हैं ऐसा ही

DEL surname

मान लें कि हम किसी पोस्ट की पसंद को बढ़ाना चाहते हैं। यहां बताया गया है कि कैसे हम इसे आसानी से कर सकते हैं, INCR . का उपयोग करके आदेश, जो परमाणु है।

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

सबसे पहले, हम पसंद का प्रारंभिक मान 10 पर सेट करते हैं, और फिर हम परमाणु रूप से पसंद के मान को बढ़ाते हैं। अब, आप शायद सोचेंगे कि पसंद बढ़ाना भी संभव है। इस तरह।

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 है, और इसे एक चर x में संग्रहीत करता है, और साथ ही, उपयोगकर्ता 2 को पसंद का वही मान मिलता है, जो 10 भी है, और इसे एक चर में संग्रहीत करता है वाई.

उपयोगकर्ता 1 पसंद (x) के मान में 1 जोड़ता है और नया मान सेट करता है, जो अब 11 है।

उपयोगकर्ता 2 वही करता है।

तो लाइक की वैल्यू 11 होती है।

लेकिन क्या यह वाकई सही है? याद रखें कि दो अलग-अलग उपयोगकर्ताओं द्वारा पसंद में दो बार वृद्धि की गई है।

पसंद का मान 12 होना चाहिए था, 11 नहीं। इसीलिए Redis INCR प्रदान करता है। आदेश, जो परमाणु है और ऐसे मुद्दों को हल करता है।

Hash DataType

रेडिस हैश अन्य प्रोग्रामिंग भाषाओं के हैश के बराबर हैं। मूल रूप से, वे मूल्यों से जुड़े क्षेत्रों के संग्रह से बने होते हैं:

उदाहरण के लिए, यहां बताया गया है कि मैं उपयोगकर्ता प्रोफ़ाइल जानकारी को हैश में कैसे संग्रहीत करूंगा।

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

सबसे पहले, हमारे हैश की कुंजी है userProfile:100034 , तो हमारे पास कुंजी मान . है सभी के माध्यम से जोड़े। उदाहरण के लिए "userId" कुंजी है और 100034' मान है। हम . का उपयोग करके विशिष्ट उपयोगकर्ता प्रोफ़ाइल जानकारी जैसे प्रथम नाम प्राप्त कर सकते हैं HGETकमांड और userId` ऐसा पसंद है।

userId = 100034
HGET userProfile:{userId} firstName

या हम GETALL . का उपयोग करके किसी विशेष उपयोगकर्ता के लिए सभी उपयोगकर्ता प्रोफ़ाइल जानकारी पुनर्प्राप्त कर सकते हैं ऐसा आदेश

userId = 100034
HGETALL userProfile:{userId}

सूची डेटा प्रकार

इससे पहले, मैंने कहा था कि, Redis में, डेटा को उसी तरह से सहेजना बहुत महत्वपूर्ण है जिस तरह से आप इसे पुनर्प्राप्त करने की योजना बना रहे हैं।

क्या होगा यदि हम सभी उपयोगकर्ताओं को अपने मंच पर लाना चाहते हैं?

हमने उपयोगकर्ता प्रोफ़ाइल जानकारी को सहेजने के लिए अभी हाल ही में हैश डेटा संरचना का उपयोग किया है। अब हमें सभी उपयोगकर्ताओं को अपने सिस्टम पर लाने की आवश्यकता है।

इसे पूरा करने का सबसे आसान तरीका यह है कि LPUSH (बाएं पुश के लिए खड़ा) कमांड का उपयोग करके सूची में प्रत्येक उपयोगकर्ता के उपयोगकर्ता आईडी को सहेजा जाए

LPUSH "users" userId

हमारी सूची से सभी उपयोगकर्ताओं को प्राप्त करने के लिए, हम LRANGE . कमांड का उपयोग करते हैं ऐसा ही

LRANGE  "users" 0  -1

ये केवल कुछ कमांड हैं जिनका उपयोग हम अपने एप्लिकेशन में करेंगे। लेकिन मैं आपसे आग्रह करता हूं कि बाकी कमांड देखने और उनका उपयोग करने का तरीका जानने के लिए रेडिस की आधिकारिक साइट देखें।

तो हमारा फुल-स्टैक एप्लिकेशन कैसे काम करेगा?

मुझे खुशी है कि आपने पूछा। तो आज, हम एक CRUD API बनाकर शुरुआत करेंगे। यहाँ उपयोग का मामला है।

हमारे पास 2 संस्थाएं हैं। उपयोगकर्ता और पोस्ट

वे एक से कई संबंध साझा करते हैं। इसलिए एक उपयोगकर्ता के पास कई पोस्ट हो सकते हैं, और एक पोस्ट केवल एक उपयोगकर्ता की हो सकती है।

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1

एक उपयोगकर्ता की अनुमति है

  • खाता बनाएं। कोई प्रमाणीकरण नहीं। आप AWS Cognito या Auth0 के साथ प्रमाणीकरण जोड़ सकते हैं।
  • अपना खाता अपडेट करें
  • उनका खाता प्राप्त करें
  • पोस्ट बनाएं
  • पोस्ट अपडेट करें
  • पोस्ट को लाइक करें
  • सभी पोस्ट की सूची प्राप्त करें

यहाँ समाधान वास्तु दृश्य है

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1 तो चलिए शुरू करते हैं।

अपस्टैश खाता बनाएं

कृपया यहाँ एक निःशुल्क Upstash खाता बनाएँ Upstash लॉगिन करें।

अपना खाता बनाने के बाद, एक Upstash डेटाबेस बनाएँ।

आपको फ्री टियर में केवल एक डेटाबेस बनाने की अनुमति है।

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1 अपने Redis डेटाबेस एंडपॉइंट पर ध्यान दें। इसे कुछ इस तरह दिखना चाहिए।redis://:2c9bb162c2444bf7ab689640bb2ead23@gusc1-smashing-bee-30249.upstash.io:00049

सर्वर रहित प्रोजेक्ट बनाना

आवश्यकताएँ

आगे बढ़ने से पहले कृपया इन निर्भरताओं को स्थापित करें

  • एडब्ल्यूएस सीएलआई

  • नोडजेएस

  • सर्वर रहित सीएलआई

    नीचे दिए गए कमांड का उपयोग करके और संकेतों का पालन करते हुए एक नया सर्वर रहित प्रोजेक्ट बनाएं।

serverless

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1

Nodejs HTTP API चुनें, अपने प्रोजेक्ट को एक नाम दें, और दर्ज करें hit दबाएं ।

मेरे सर्वर रहित प्रोजेक्ट की प्रारंभिक संरचना यहां दी गई है।

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1

उस फ़ोल्डर के अंदर, कमांड के साथ एक नया नोड प्रोजेक्ट प्रारंभ करें

npm init

इसके बाद, रेडिस क्लाइंट को

. के साथ स्थापित करें
npm install ioredis

इसके अलावा, एक सार्वभौमिक रूप से अद्वितीय पहचानकर्ता (यूयूआईडी) निर्भरता स्थापित करें। हम इस परियोजना में इसका व्यापक रूप से उपयोग करेंगे।

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 फोल्डर बनाएं और पोस्ट . इन दोनों फ़ोल्डरों में उनके संबंधित उपयोग के मामलों के लिए लैम्ब्डा फ़ंक्शन होंगे।

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1

आइए हमारे एपीआई एनपॉइंट बनाना शुरू करें

उपयोगकर्ता बनाएं

हम चाहते हैं कि उपयोगकर्ता अपने लिए एक खाता बना सकें।

कोई प्रमाणीकरण नहीं। उन्हें बस इतना करना है कि उन्हें सबमिट करना है

  • उपयोगकर्ता नाम
  • पहला नाम
  • उपनाम
  • प्रोफ़ाइल तस्वीर

उपयोगकर्ता . में एक फ़ाइल बनाएं create.js . नाम का फोल्डर ।

फ़ाइल के शीर्ष पर, रेडिस डेटाबेस URL का उपयोग करके रेडिस क्लाइंट को आयात और इंस्टेंट करें जिसे हमने serverless.yml में एक पर्यावरण चर के रूप में सहेजा है। फ़ाइल।

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

हम यूयूआईडी निर्भरता भी आयात करते हैं, क्योंकि हम इसका उपयोग उपयोगकर्ताओं के लिए विशिष्ट आईडी बनाने के लिए करेंगे।

सबसे पहले, हमें उपयोगकर्ता प्रोफ़ाइल . को सहेजने के लिए डेटा संरचना की आवश्यकता है userId's . को बचाने के लिए जानकारी और अन्य डेटा संरचना एप्लिकेशन में सभी उपयोगकर्ताओं की।

हैश और सूची डेटाटाइप याद रखें?

उपयोगकर्ता प्रोफ़ाइल जानकारी को सहेजने के लिए हैश डेटाटाइप। डेटाटाइप कुंजी userItem:${userId} . पर ध्यान दें

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

फिर हम बनाए गएuserId . को सेव करते हैं उपयोगकर्ताओं . नामक सूची में

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}`);

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1

serverless.yml को अपडेट करना न भूलें इस समापन बिंदु को प्रतिबिंबित करने के लिए।

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

हमारे फंक्शन का नाम है createUser , और यह create.js . नामक फ़ाइल में स्थित है जो user . नामक फोल्डर के अंदर होता है इसलिए हैंडलर user/create.createUser

पथ पर ध्यान दें /user

क्रिएटयूजर फ़ंक्शन पोस्ट का उपयोग करता है एचटीटीपी विधि।

यहां 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}

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1

उपयोगकर्ता प्राप्त करें

HGETALL का उपयोग करना कमांड और हैश कुंजी, हम किसी विशेष उपयोगकर्ता के लिए उपयोगकर्ता प्रोफ़ाइल जानकारी प्राप्त कर सकते हैं।

ध्यान रखें कि हम HGET . का भी उपयोग कर सकते हैं उपयोगकर्ता विशिष्ट जानकारी जैसे प्रथम नाम या अंतिम नाम इत्यादि प्राप्त करने के लिए आदेश।

आइए कोड देखें

उपयोगकर्ता . में एक फ़ाइल बनाएं 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

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1

उपयोगकर्ताओं की सूची बनाएं

जब हमने उपयोगकर्ता बनाने के लिए हैंडलर लिखा था, तो याद रखें कि हमने धक्का दिया था (LPUSH ) userId एक उपयोगकर्ताओं . में है सूची।

अब, हमें LRANGE . कमांड का उपयोग करके उन सभी आईडी को हथियाना होगा ।

<ब्लॉकक्वॉट>

नोट:यदि पदों की सूची बहुत बड़ी होने लगती है, तो LRANGE बहुत कुशल नहीं है, और हम उन तत्वों तक पहुंच बनाना चाहते हैं जो सूची के बीच में हैं, क्योंकि रेडिस सूचियां लिंक्ड सूचियों द्वारा समर्थित हैं। यदि सिस्टम को लाखों आइटमों के डीप पेजिनेशन के लिए डिज़ाइन किया गया है, तो इसके बजाय सॉर्ट किए गए सेट का सहारा लेना बेहतर है।

सभी उपयोगकर्ता आईडी प्राप्त करने के बाद, हम फिर प्रत्येक 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

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1

और यह उपयोगकर्ताओं . के लिए है समापन बिंदु। आप आगे बढ़ सकते हैं और अपना ऐप परिनियोजित कर सकते हैं, अगर आपने पहले से ऐसा नहीं किया है।

sls deploy

पोस्ट

उपयोगकर्ता द्वारा खाता बनाने के बाद, उन्हें अनुमति दी जानी चाहिए

  • पोस्ट बनाएं
  • आईडी द्वारा पोस्ट प्राप्त करें
  • उनके पोस्ट की सूची प्राप्त करें
  • किसी पोस्ट को पसंद या नापसंद करना (किसी पोस्ट पर प्रतिक्रिया देना)

आइए शुरू करें।

पोस्ट बनाएं

पोस्ट बनाने के लिए आवश्यक पैरामीटर हैं

  • उपयोगकर्ता आईडी
  • postId(UUID द्वारा स्वतः उत्पन्न)
  • पोस्टटेक्स्ट
  • पोस्टइमेज
  • बनाया गया

3 कदम शामिल हैं।

  1. पोस्ट विवरण को हैश कुंजी पर सेट करने के लिए HMSET कमांड का उपयोग करें postItem:${postId}
  2. LPUSH कमांड का उपयोग पोस्ट आईडी को पोस्ट की सूची में जोड़ने के लिए करें ।
  3. userPost:${userId} की सूची में postId जोड़ने के लिए LPUSH कमांड का उपयोग करें ।

हम इस कार्य को कालानुक्रमिक रूप से निष्पादित करने के लिए एक पाइपलाइन का उपयोग करेंगे।

पोस्ट में एक फाइल बनाएं 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

परिनियोजन और परीक्षण करें।

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1

आईडी द्वारा पोस्ट प्राप्त करें

आईडी द्वारा पोस्ट प्राप्त करते समय, हम पोस्ट एडमिन के विवरण प्राप्त करना और संलग्न करना चाहते हैं, साथ ही पोस्ट की अब तक की प्रतिक्रियाओं (पसंद) की संख्या के साथ।

मुझे पता है कि हमने अभी तक किसी पोस्ट को लाइक या अनलाइक नहीं किया है, बस वहीं रुकें, हम उस तक पहुंच रहे हैं। 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}

फिर, चूंकि पोस्ट ऑब्जेक्ट में उस उपयोगकर्ता का उपयोगकर्ता आईडी है जिसने पोस्ट (पोस्ट व्यवस्थापक) बनाया है, हम userItem:${postItem.userId} का उपयोग करते हैं उस उपयोगकर्ता के लिए उपयोगकर्ता विवरण प्राप्त करने के लिए।

याद रखें कि यह ठीक वही कुंजी थी जिसका उपयोग हमने ऊपर उपयोगकर्ता समापन बिंदु बनाने में किया था।

तीसरा, हमें get . का उपयोग करके postReactionCount मिलता है कमांड और एक कुंजी postReactionsCount:${postId} जिसका उपयोग हम बाद में पोस्ट रिएक्शन्सकाउंट को सेव करने के लिए करेंगे।

परिनियोजित और परीक्षण करें

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1

किसी पोस्ट पर प्रतिक्रिया दें

यह संपूर्ण एप्लिकेशन का सबसे दिलचस्प समापन बिंदु है। लिखने में मज़ा आया।

एक उपयोगकर्ता को किसी पोस्ट को पसंद या नापसंद करने की अनुमति है। अब, जब कोई उपयोगकर्ता लाइक बटन पर क्लिक करता है, तो हम पहले जांचते हैं कि क्या इस उपयोगकर्ता ने पोस्ट को पहले पसंद किया था।

यदि हाँ, तो हम, पोस्ट के विपरीत। नहीं तो हमें पोस्ट पसंद आती है।

क्या आप समझते हैं?

बिल्कुल इंस्टाग्राम या ट्विटर की तरह।

पोस्ट फोल्डर में react_to_post.js नामक फाइल बनाएं

समापन बिंदु userId takes लेता है और postId पथ पैरामीटर के रूप में।

आइए एक नए आदेश को देखें। क्रमबद्ध सेट। हम पोस्ट को पसंद करने वाले उपयोगकर्ता के उपयोगकर्ता आईडी और पोस्ट को पसंद करने पर टाइमस्टैम्प जोड़ने के लिए एक क्रमबद्ध सेट का उपयोग करेंगे।

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

कुंजी है postReactions:${postId}

क्रमबद्ध सेट Z से शुरू होते हैं। Redis दस्तावेज़ से, zadd

<ब्लॉकक्वॉट>

सभी निर्दिष्ट सदस्यों को निर्दिष्ट स्कोर के साथ कुंजी पर संग्रहीत सॉर्ट किए गए सेट में जोड़ता है। एकाधिक स्कोर/सदस्य जोड़े निर्दिष्ट करना संभव है। यदि कोई निर्दिष्ट सदस्य पहले से ही सॉर्ट किए गए सेट का सदस्य है, तो स्कोर अपडेट किया जाता है और सही क्रम सुनिश्चित करने के लिए तत्व को सही स्थिति में पुन:सम्मिलित किया जाता है।

अगला कदम . का उपयोग करके postReactionsCount:${postId} को बढ़ाना है incr` कमांड।

याद रखें कि हमने पोस्ट-रिएक्शन गिनती प्राप्त करने के लिए आईडी एंडपॉइंट द्वारा पोस्ट प्राप्त करने में उपरोक्त कुंजी का उपयोग किया था।

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

अंत में, हम उपयोगकर्ता पोस्ट प्रतिक्रिया विवरण को हैश में सहेजते हैं

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

इन सब के आधार पर, यहां उपलब्ध पहुंच पैटर्न हैं।

  • हम प्रतिक्रिया के बाद की संख्या प्राप्त कर सकते हैं।
  • हम उन सभी उपयोगकर्ताओं को प्राप्त कर सकते हैं जिन्होंने किसी पोस्ट पर प्रतिक्रिया दी, आरोही या अवरोही क्रम में
  • हम उन सभी पोस्टों को प्राप्त कर सकते हैं जिन पर उपयोगकर्ता ने प्रतिक्रिया दी है।

हमने पहले उल्लेख किया था कि, हमें यह देखने के लिए जांच करने की आवश्यकता है कि क्या किसी उपयोगकर्ता ने पहले किसी पोस्ट को पसंद किया था। यदि हाँ, तो हम उस पोस्ट को नापसंद करते हैं। नहीं तो हमें पोस्ट पसंद आती है

हम zscore . का उपयोग करेंगे इसके लिए आदेश।

<ब्लॉकक्वॉट>

कुंजी पर सॉर्ट किए गए सेट में सदस्य का स्कोर लौटाता है। यदि सदस्य सॉर्ट किए गए सेट में मौजूद नहीं है, या कुंजी मौजूद नहीं है, तो शून्य वापस आ जाता है।

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

अगर zscore शून्य है, तो उपयोगकर्ता ने इसे पसंद नहीं किया है। वरना, उपयोगकर्ता ने इसे पसंद किया है।

यहां देखें कि पूरा कोड कैसा दिखता है

"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

परिनियोजन और परीक्षण करें।

फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (REDIS) के साथ फुलस्टैक सर्वर रहित ऐप - भाग 1

अपने एपीआई परीक्षक (मैं पोस्टमैन का उपयोग करता हूं) पर भेजें बटन को कई बार दबाएं और देखें कि "पोस्टरिएक्शनकाउंट" 0 और 1 के बीच कैसे टॉगल करता है।

UserId बदलें और दोबारा जांच करें।

कई अन्य एक्सेस पैटर्न और सुधार हैं जिन्हें आप इस एपीआई में जोड़ सकते हैं।

इस पर विस्तार करने और अधिक जानने के लिए आप कैसे चुनौती स्वीकार करते हैं।

यहां संपूर्ण स्रोत कोड का लिंक दिया गया है

मैं पूरी तरह से रेडिस के सीखने की अवस्था को नहीं मानता, और यह तथ्य कि यह मुझे डेटा को उसी तरह से सहेजने की अनुमति देता है जिस तरह से मैं इसे पुनः प्राप्त करूंगा।

ऐप विकसित करना शुरू करने से पहले हमेशा अपने एक्सेस पैटर्न को जानें।

मुझे यह रचना लिखने में बहुत मज़ा आया, आशा है कि आपने एक या दो चीज़ें सीखी होंगी।

क्या मैंने कहीं गलती की? आप जैसा सुपर सयान मुझे बताने में संकोच नहीं करेगा।

अगले लेख में, हम इस एपीआई का उपभोग करने के लिए एक फ़्लटर ऐप बनाएंगे। बने रहें।

हैप्पी कोडिंग कॉमरेड✌🏿

संदर्भ

  • अपस्टैश डॉक्स
  • रेडिस
  • स्पंदन
  • इंटरनेट से डेटा लाया जा रहा है

  1. सर्वर रहित रेडिस और रिएक्ट नेटिव के साथ इन-ऐप घोषणाएं

    मोबाइल एप्लिकेशन में, ऐप में अंतिम उपयोगकर्ताओं को कुछ जानकारी, चेतावनियां या मार्गदर्शन भेजने की आवश्यकता हो सकती है। ऐसा करने का एक तरीका उपयोगकर्ताओं को इन-ऐप घोषणाएं भेजना है। इस ब्लॉग पोस्ट में, हम सर्वर रहित रेडिस वाले उपयोगकर्ताओं को घोषणाएं भेजने का तरीका दिखाने के लिए एक मोबाइल एप्लिकेशन व

  1. Nuxt 3 और Serverless Redis के साथ शुरुआत करना

    परिचय यदि आपको कभी ऐसा ऐप बनाना पड़े जो एप्लिकेशन के उपयोग को ट्रैक करता हो, संसाधनों के उपयोग को प्रतिबंधित करता हो या ऐप के प्रदर्शन को बढ़ाने के लिए कैश से डेटा प्राप्त करता हो, तो आपको पता होगा कि रेडिस इन आवश्यकताओं का उत्तर है! रेडिस इन-मेमोरी, की-वैल्यू डेटाबेस है। यह ओपन सोर्स है और इसका मत

  1. फ़्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश (रेडिस) के साथ फुलस्टैक सर्वरलेस ऐप - भाग 2

    इस ट्यूटोरियल श्रृंखला के भाग 2 में आपका स्वागत है। पहले भाग में, हमने देखा कि Upstash, Serverless Framework और Redis का उपयोग करके REST API कैसे बनाया जाता है। इस भाग में, हम अपने REST API समापन बिंदुओं का उपभोग करने के लिए, Flutter का उपयोग करके एक मोबाइल एप्लिकेशन बनाएंगे। आइए शुरू करें 🙃 सबस