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

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 1

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

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

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

अपस्टैश आपके लिए डेटाबेस को कॉन्फ़िगर और मैनेज करता है। यह DynamoDB और Fauna जैसे अन्य डेटाबेस का एक मजबूत विकल्प है, जिसमें निम्नलिखित फायदे हैं:

  • कम लेटेंसी
  • उपयोग में आसानी, बिल्कुल REDIS API की तरह।

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

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

अपस्टैश के साथ:

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

आज ही अपस्टैश पर फ्री में शुरुआत करें

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

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

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

यह कई डेटा स्ट्रक्चर का समर्थन करता है जैसे:

  • स्ट्रिंग्स
  • हैश
  • लिस्ट
  • सेट
  • रेंज क्वेरी के साथ सॉर्टेड सेट
  • बिटमैप्स
  • हाइपरलॉगलॉग्स
  • जियोस्पेशियल इंडेक्स

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

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

SET surname Rosius

जहां surname की है और Rosius वैल्यू है।

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

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

रेडिस में डेटा स्थायी रूप से स्टोर होता है। तो मैं 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 है, और इसे वेरिएबल x में स्टोर करता है, और उसी समय, यूजर 2 लाइक्स का वही मान प्राप्त करता है, जो 10 भी है, और इसे वेरिएबल y में स्टोर करता है।

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

यूजर 2 वही करता है।

तो लाइक्स का मान 11 है।

लेकिन क्या यह वास्तव में सही है? याद रखें कि लाइक्स को 2 अलग-अलग यूजर्स द्वारा दो बार बढ़ाया गया है।

लाइक्स का मान 12 होना था, न कि 11। इसीलिए रेडिस INCR कमांड प्रदान करता है, जो एटॉमिक है और ऐसी समस्याओं को हल करता है।

हैश डेटा टाइप

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

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

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

या हम HGETALL कमांड का उपयोग करके किसी विशेष यूजर के लिए सभी यूजर प्रोफाइल जानकारी पुनः प्राप्त कर सकते हैं:

userId = 100034
HGETALL userProfile:{userId}

लिस्ट डेटा टाइप

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

क्या होगा अगर हम अपने प्लेटफॉर्म पर सभी यूजर्स को प्राप्त करना चाहते हैं?

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

इसे पूरा करने का सबसे आसान तरीका है हर यूजर के userId को LPUSH (लेफ्ट पुश) कमांड का उपयोग करके users नामक लिस्ट में सेव करना:

LPUSH "users" userId

हमारी लिस्ट से सभी यूजर्स प्राप्त करने के लिए, हम LRANGE कमांड का उपयोग करते हैं:

LRANGE "users" 0 -1

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

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

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

हमारे पास 2 एंटिटी हैं: Users और Posts।

उनका एक-से-बहुत संबंध है। तो एक यूजर के कई पोस्ट हो सकते हैं, और एक पोस्ट केवल एक यूजर से संबंधित हो सकता है।

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 1

एक यूजर को अनुमति है:

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

यहां समाधान का आर्किटेक्चरल व्यू है:

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 1

अपस्टैश अकाउंट बनाएं

कृपया यहां अपस्टैश लॉगिन पर फ्री अपस्टैश अकाउंट बनाएं।

अपना अकाउंट बनाने के बाद, एक अपस्टैश डेटाबेस बनाएं।

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

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

सर्वरलेस प्रोजेक्ट बनाना

पूर्वापेक्षाएँ

आगे बढ़ने से पहले कृपया इन डिपेंडेंसीज को इंस्टॉल करें:

  • AWS CLI
  • NodeJS
  • सर्वरलेस CLI

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

serverless

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 1

Node.js HTTP API चुनें, अपने प्रोजेक्ट को नाम दें, और enter दबाएं।

मेरे सर्वरलेस प्रोजेक्ट की प्रारंभिक संरचना यहां है:

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 1

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

npm init

अगला, रेडिस क्लाइंट इंस्टॉल करें:

npm install ioredis

इसके अलावा, यूनिवर्सली यूनिक आइडेंटिफायर (uuid) डिपेंडेंसी इंस्टॉल करें। हम इस प्रोजेक्ट में इसका बड़े पैमाने पर उपयोग करेंगे।

npm install uuid

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

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 1

चलिए हमारे API एंडपॉइंट्स बनाना शुरू करते हैं।

यूजर बनाएं

हम यूजर्स को अपने लिए अकाउंट बनाने में सक्षम बनाना चाहते हैं।

कोई ऑथेंटिकेशन नहीं। उन्हें बस अपना सबमिट करना होगा:

  • यूजरनेम
  • पहला नाम
  • अंतिम नाम
  • प्रोफाइल पिक्चर

user फोल्डर में create.js नाम की एक फाइल बनाएं।

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

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

हम uuid डिपेंडेंसी भी इम्पोर्ट करते हैं, क्योंकि हम इसका उपयोग यूजर्स के लिए यूनिक ID बनाने के लिए करेंगे।

सबसे पहले, हमें user profile जानकारी को सेव करने के लिए एक डेटा स्ट्रक्चर और एप्लिकेशन में सभी यूजर्स के 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 ऑपरेशन भेजने होंगे। उन्हें एक के बाद एक भेजना संभव है, लेकिन यह इष्टतम नहीं है।

अपस्टैश पाइपलाइनिंग नामक फीचर के माध्यम से बैच ऑपरेशन का समर्थन करता है।

तो सिंगल कमांड भेजने और रिस्पॉन्स की प्रतीक्षा करने के बजाय, हम कई कमांड भेज सकते हैं और रिस्पॉन्स उसी तरह वापस आएगा जैसे हमने कमांड भेजे थे।

तो पाइपलाइन का उपयोग करने के बाद हमारा ऑपरेशन ऐसा दिखेगा:

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 के माध्यम से रिस्पॉन्स के रूप में वापस कर सकते हैं।

// सेव किए गए यूजर आइटम को प्राप्त करें और प्रदर्शित करें
const userItem = await client.hgetall(`userItem:${userId}`);

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 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);
}

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

  // यहां, हम कई रिक्वेस्ट करने के लिए पाइपलाइन का उपयोग करते हैं
  // सबसे पहले, हम यूजर डिटेल्स को की (`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)
  );

  // सेव किए गए यूजर आइटम को प्राप्त करें और प्रदर्शित करें
  const userItem = await client.hgetall(`userItem:${userId}`);
  console.log(userItem);

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

यूजर अपडेट करें

यूजर्स समय-समय पर अपने प्रोफाइल को अपडेट करना पसंद करेंगे। इसलिए यूजर अपडेट एंडपॉइंट प्रदान करना उचित है।

इस ऑपरेशन के लिए हमें केवल HMSET कमांड और userId की आवश्यकता है।

रेडिस डॉक्यूमेंटेशन से, यहां ठीक बताया गया है कि 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);
}

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

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

  // सेव किए गए यूजर आइटम को प्राप्त करें और प्रदर्शित करें
  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} के रूप में पास करते हैं।

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 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}`);

  // सेव किए गए यूजर आइटम को प्राप्त करें और प्रदर्शित करें
  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

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 1

यूजर्स सूचीबद्ध करें

जब हम यूजर बनाने के लिए हैंडलर लिख रहे थे, याद रखें हमने LPUSH का उपयोग करके userId को users लिस्ट में लेफ्ट पुश किया था।

अब, हमें उन सभी ID को LRANGE कमांड का उपयोग करके प्राप्त करना होगा।

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

सभी 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

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 1

और यह users एंडपॉइंट्स के लिए है। आप आगे बढ़कर अपना ऐप डिप्लॉय कर सकते हैं, अगर आपने पहले से नहीं किया है।

sls deploy

पोस्ट

एक यूजर द्वारा अकाउंट बनाने के बाद, उन्हें अनुमति दी जानी चाहिए:

  • पोस्ट बनाएं
  • ID द्वारा पोस्ट प्राप्त करें
  • अपने पोस्ट की सूची प्राप्त करें
  • पोस्ट को लाइक या अनलाइक करें (पोस्ट पर प्रतिक्रिया दें)

चलिए शुरू करते हैं।

पोस्ट बनाएं

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

  • userId
  • postId (UUID द्वारा ऑटो-जेनरेटेड)
  • postText
  • postImage
  • createdOn

3 स्टेप्स शामिल हैं:

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

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

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

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

  // सेव किए गए पोस्ट आइटम को प्राप्त करें और प्रदर्शित करें
  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

डिप्लॉय और टेस्ट करें।

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 1

ID द्वारा पोस्ट प्राप्त करें

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

मुझे पता है कि हमने अभी तक पोस्ट को लाइक या अनलाइक करना नहीं देखा है, बस धैर्य रखें, हम वहां पहुंच रहे हैं। post फोल्डर में 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}`);

  // सेव किए गए पोस्ट आइटम को प्राप्त करें और प्रदर्शित करें
  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 कमांड और एक की postReactionsCount:${postId} का उपयोग करके postReactionCount प्राप्त करते हैं जिसका उपयोग हम बाद में postReactionsCount को सेव करने के लिए करेंगे।

डिप्लॉय और टेस्ट करें।

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 1

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

यह पूरे एप्लिकेशन का सबसे दिलचस्प एंडपॉइंट है। इसे लिखना मजेदार था।

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

अगर हां, तो हम पोस्ट को अनलाइक करते हैं। अन्यथा, हम पोस्ट को लाइक करते हैं।

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

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

post फोल्डर में react_to_post.js नाम की एक फाइल बनाएं।

एंडपॉइंट userId और postId को पथ पैरामीटर के रूप में लेता है।

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

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

की है postReactions:${postId}।

सॉर्टेड सेट Z से शुरू होते हैं। रेडिस डॉक्यूमेंटेशन से, zadd:

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

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

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

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

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

  // पहले जांचें कि क्या यूजर ने पहले पोस्ट को लाइक किया है
  const hasUserReacted = await client.zscore(
    `postReactions:${postId}`,
    data.userId
  );

  if (hasUserReacted == null) {
    // यूजर ने प्रतिक्रिया नहीं दी है।
    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 {
    // यूजर ने पहले ही प्रतिक्रिया दी है, तो अनरिएक्ट करें
    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
      )
    );
  }

  // पोस्ट रिएक्शन काउंट वापस करें
  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

डिप्लॉय और टेस्ट करें।

फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस ऐप बनाएं - भाग 1

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

UserId बदलें और फिर से जांच करें।

इस API में जोड़ने के लिए बहुत सारे अन्य एक्सेस पैटर्न और फिक्स हैं।

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

यहां पूरा सोर्स कोड का लिंक है।

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

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

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

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

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

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

संदर्भ

  • अपस्टैश डॉक्स
  • रेडिस
  • फ्लटर
  • इंटरनेट से डेटा लाना
  1. Serverless Redis और React Native के साथ त्वरित इन-ऐप घोषणाएं Serverless Redis और React Native के साथ त्वरित इन-ऐप घोषणाएं

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

  1. नक्स्ट 3 ऐप्स को सर्वरलेस रेडिस के साथ लॉन्च करें: तेज़ परफॉरमेंस के लिए नक्स्ट 3 ऐप्स को सर्वरलेस रेडिस के साथ लॉन्च करें: तेज़ परफॉरमेंस के लिए

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

  1. फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस मोबाइल ऐप बनाएं - भाग 2 फ्लटर, सर्वरलेस फ्रेमवर्क और अपस्टैश रेडिस के साथ फुल-स्टैक सर्वरलेस मोबाइल ऐप बनाएं - भाग 2

    इस ट्यूटोरियल सीरीज के भाग 2 में आपका स्वागत है। पहले भाग में, हमने देखा कि अपस्टैश, सर्वरलेस फ्रेमवर्क और रेडिस का उपयोग करके REST API कैसे बनाया जाता है। इस भाग में, हम अपने REST API एंडपॉइंट्स का उपभोग करने के लिए फ्लटर का उपयोग करके एक मोबाइल एप्लिकेशन बनाएंगे। चलिए शुरू करते हैं 🙃 सबसे पहले