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

Blitz.js और Redis . के साथ टू-डू सूची बनाना

Blitz.js एक रिएक्ट फ्रेमवर्क है जिसे मूल रूप से Next.js से फोर्क किया गया था। आज हम एक Blitz.js To-Do एप्लिकेशन बनाएंगे जो कार्यों को Upstash में संग्रहीत करता है। आगे की हलचल के बिना, चलिए शुरू करते हैं!

सेटअप

आरंभ करने के लिए आपको अपने कंप्यूटर पर Blitz.js इंस्टॉल करना होगा।

एनपीएम:

npm install -g blitz --legacy-peer-deps

सूत:

yarn global add blitz

एक नया Blitz.js ऐप बनाने के लिए, blitz new . का उपयोग करें और निर्देशिका में सीडी।

blitz new blitzjs-todo && cd blitzjs-todo

बढ़िया, अब हमारी वेबसाइट को स्टाइल करने के लिए TailwindCSS इंस्टॉल करें।

blitz install tailwind

अंत में, Upstash JS SDK को स्थापित करें ताकि Upstash API को कॉल करना आसान हो सके।

एनपीएम:

npm i @upstash/redis

सूत:

yarn i @upstash/redis

इस बिंदु पर, आपको blitz dev चलाना चाहिए यह सुनिश्चित करने के लिए कि सब कुछ ठीक से काम कर रहा है। खाता बनाने और साइन इन करने का भी प्रयास करें। यदि आपने अब तक सब कुछ सही ढंग से किया है तो यह इस तरह दिखना चाहिए।

Blitz.js और Redis . के साथ टू-डू सूची बनाना

इसके अलावा, आपकी फ़ाइल संरचना इस तरह दिखनी चाहिए:

Blitz.js और Redis . के साथ टू-डू सूची बनाना

इन्हें कॉपी करें UPSTASH_REDIS_REST_URL और UPSTASH_REDIS_REST_TOKEN Upstash कंसोल से .env . नामक फ़ाइल में अभी के लिए। यह इस तरह दिखना चाहिए:

# This env file should be checked into source control
# This is the place for default values for all environments
# Values in `.env.local` and `.env.production` will override these values

UPSTASH_REDIS_REST_URL=YOUR_URL_HERE
UPSTASH_REDIS_REST_TOKEN=YOUR_TOKEN_HERE

हमने अपना Blitz.js एप्लिकेशन अभी पूरी तरह से सेट कर लिया है! आइए अपनी टू-डू सूची को लागू करना शुरू करें।

कार्यान्वयन

Blitz.js में निर्मित उपयोगकर्ता प्रमाणीकरण के साथ आता है! आइए प्रत्येक उपयोगकर्ता के लिए निजी टू-डू सूचियां बनाने के लिए इसका लाभ उठाएं।

सबसे पहले, Upstash JS SDK को /lib/redis.ts में इनिशियलाइज़ करें

import { Redis } from "@upstash/redis";
const redis = Redis.fromEnv();
export default redis;

हमें 3 . बनाना होगा हमारी टू-डू सूचियों तक पहुंचने के लिए विभिन्न एपीआई रूट।

app/api पर नेविगेट करें और getall.ts . नाम की एक फाइल बनाएं . एक बार ऐसा करने के बाद, निम्न कोड को इसमें पेस्ट करें:

import { BlitzApiRequest, BlitzApiResponse, getSession } from "blitz";
import redis from "../../lib/redis";

export const handler = async (req: BlitzApiRequest, res: BlitzApiResponse) => {
  const session = await getSession(req, res);
  if (!session.userId) {
    res.status(401).json({ error: `Do not tamper with this route!` });
  } else {
    await redis
      .lrange(String(session.userId), 0, 100)
      .then((data) => res.status(200).json({ data: data, success: true }))
      .catch((error) => res.status(500).json({ error: error }));
  }
};
export default handler;

आइए देखें कि यह एपीआई रूट कैसे काम करता है, चरण दर चरण। सबसे पहले, हम मार्ग के लिए अनुरोध करते हैं। मार्ग पर ही, हम पुष्टि करते हैं कि उपयोगकर्ता लॉग इन है। यदि कोई उपयोगकर्ता नहीं है, तो हम "अधिकृत नहीं" प्रतिक्रिया लौटाते हैं। अगर वहाँ है एक उपयोगकर्ता, फिर हम सूची में वर्तमान में मौजूद सभी टू-डॉस को खोजने के लिए अपना अपस्टैश रेडिस डेटाबेस प्राप्त करते हैं। इससे लगभग सौ टू-डॉस प्राप्त होंगे।

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

प्रश्न:रुको, हम पहली बार में टू-डॉस कैसे जोड़ने वाले हैं?ए:अच्छा सवाल! चलिए इसे आगे करते हैं!

एक बार फिर, निम्न कोड को add.ts . नामक एक नई फ़ाइल में पेस्ट करें app/api में ।

"ब्लिट्ज" से
import { BlitzApiRequest, BlitzApiResponse, getSession } from "blitz";
import redis from "../../lib/redis";
const handler = async (req: BlitzApiRequest, res: BlitzApiResponse) => {
  const session = await getSession(req, res);
  if (req.method !== "POST" || !req.body.data || !session.userId) {
    res.status(401).json({ error: `Do not tamper with this route!` });
  } else {
    let todo = encodeURI(req.body.data);
    await redis
      .lpush(String(session.userId), todo)
      .then(() => res.status(200).json({ success: true }))
      .catch(() => res.status(500).json({ error: "Error adding data." }));
  }
};
export default handler;

यह एपीआई मार्ग पिछले एक के समान है, लेकिन ध्यान दें कि हमने पांचवीं पंक्ति में और अधिक चेक जोड़े हैं। ऐसा इसलिए है क्योंकि यह अनुरोध GET नहीं है अनुरोध, बल्कि, यह एक POST है अनुरोध। ध्यान दें कि हम तीन चीजों की जांच कैसे करते हैं। सबसे पहले, हम सुनिश्चित करते हैं कि अनुरोध वास्तव में एक POST है अनुरोध। इसके बाद, हम सुनिश्चित करते हैं कि req.body.data . में JSON या टेक्स्ट है . अंत में, हम सुनिश्चित करते हैं कि उपयोगकर्ता लॉग इन है। यदि ये सभी छोटे चेक पास हो जाते हैं, तो हम अपने टू-डू को अपस्टैश पर अपनी रेडिस सूची में धकेल सकते हैं। यदि लाते समय किसी प्रकार की त्रुटि होती है, तो हम .catch . का उपयोग करके 500 वापस कर सकते हैं ।

आखिरी रास्ता जो हमें जोड़ने की जरूरत है, वह है हमारे टू-डॉस को हटाना। एक बार जब आप कुछ खत्म कर लेते हैं, तो आपको निश्चित रूप से इसे पार करना होगा! आइए अपना आखिरी एपीआई रूट app/api/remove.ts . में जोड़ें . निम्न कोड को फ़ाइल में कॉपी करें:

"ब्लिट्ज" से
import { BlitzApiRequest, BlitzApiResponse, getSession } from "blitz";
import redis from "../../lib/redis";
const handler = async (req: BlitzApiRequest, res: BlitzApiResponse) => {
  const session = await getSession(req, res);
  if (req.method !== "POST" || !req.body.data || !session.userId) {
    res.status(401).json({ error: `Do not tamper with this route!` });
  } else {
    let todo = encodeURI(req.body.data);
    await redis
      .lrem(String(session.userId), 1, todo)
      .then(() => res.status(200).json({ success: true }))
      .catch(() => res.status(500).json({ error: "Error removing data." }));
  }
};
export default handler;

कुछ ऐसा ही नोटिस करें? ऐसा इसलिए है क्योंकि यह मार्ग लगभग add . के समान है एपीआई मार्ग। यहाँ मुख्य अंतर यह है कि हम LREM . का उपयोग कर रहे हैं , नहीं LPUSH , Redis से किसी आइटम को हटाने के लिए।

बिल्डिंग द फ़्रंटएंड

शुरू करने के लिए, आइए app/pages/index.js . से सब कुछ हटा दें और हमारी टू-डू सूची को चरण दर चरण लिखें।

फ़ाइल के शीर्ष पर, इन आयातों को इसमें चिपकाएँ।

import { Link, BlitzPage, useMutation, Routes, getAntiCSRFToken } from "blitz";
import { useRef, useEffect, useState, Suspense } from "react";
import Layout from "app/core/layouts/Layout";
import { useCurrentUser } from "app/core/hooks/useCurrentUser";
import logout from "app/auth/mutations/logout";

हम अपनी टू-डू सूची की मुख्य कार्यक्षमता बनाने के लिए रिएक्ट हुक का उपयोग करेंगे। आइए सूची की कुछ मुख्य विशेषताओं को लागू करें।

const Main = () => {
  const todoRef = useRef<HTMLInputElement>(null)
  const [todos, setTodos] = useState([])
  const currentUser = useCurrentUser()
  const [logoutMutation] = useMutation(logout)
  const handleAddTodo = async (e) => {
    e.preventDefault()
    const antiCSRFToken = await getAntiCSRFToken()
    const response = await fetch("/api/add", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "anti-csrf": antiCSRFToken,
      },
      body: JSON.stringify({ data: todoRef.current?.value }),
    })
    const data = await response.json()
    if (data.success) {
      todoRef.current!.value = ""
      fetchTodos()
    }
  }
  const handleRemoveTodo = async (id) => {
    const antiCSRFToken = await getAntiCSRFToken()
    const response = await fetch("/api/remove", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "anti-csrf": antiCSRFToken,
      },
      body: JSON.stringify({ data: id }),
    })
    const data = await response.json()
    if (data.success) {
      fetchTodos()
    }
  }
  const fetchTodos = async () => {
    const antiCSRFToken = await getAntiCSRFToken()
    const response = await fetch("/api/getall", {
      method: "GET",
      headers: {
        "anti-csrf": antiCSRFToken,
      },
    })
    const res = await response.json()
    setTodos(res.data)
  }
  useEffect(() => {
    fetchTodos()
  }, [])

  if (currentUser) {
    return (
      <>
        <button
          className="mt-4 px-2 py-1 border-2 border-black hover:bg-gray-400 mb-3"
          onClick={async () => {
            await logoutMutation()
          }}
        >
          Logout
        </button>
        <div>
          User id: <code>{currentUser.id}</code>
          <br />
          User email: <code>{currentUser.email}</code>
        </div>
        <form className="mt-2" onSubmit={handleAddTodo}>
          <p>add a todo:</p>
          <input
            ref={todoRef}
            className="w-full border-black border-2 focus:outline-none text-center"
          />
        </form>
        <div className="flex flex-col gap-2 mt-4 bg-gray-300 rounded-md">
          {(todos as string[]).map((todo: string, index: number) => (
            <div className="flex items-center p-3 rounded-md bg-gray-300" key={index}>
              <button
                onClick={() => handleRemoveTodo(todo)}
                className="flex items-center mr-4 justify-center w-5 h-5 rounded-[0.25rem] border border-solid border-gray-500 shadow-sm hover:bg-gray-700"
              ></button>

              <span>{todo}</span>
            </div>
          ))}
        </div>
      </>
    )
  } else {
    return (
      <div className="flex flex-col gap-4 text-center">
        <Link href={Routes.SignupPage()}>
          <a className="mt-4 px-2 py-1 border-2 border-black hover:bg-gray-400">
            <strong>Sign Up</strong>
          </a>
        </Link>
        <Link href={Routes.LoginPage()}>
          <a className="mt-4 px-2 py-1 border-2 border-black hover:bg-gray-400">
            <strong>Login</strong>
          </a>
        </Link>
      </div>
    )
  }
}

<Main/> घटक हमारे आवेदन का मूल है। इसके कोड को करीब से देखने पर पता चलता है कि हम इसका उपयोग कैसे करते हैं। हमारे घटक के शीर्ष पर, हम अपने आवेदन के लिए राज्य को प्रारंभ करते हैं। हम एक ref . भी घोषित करते हैं हमारे "नए टू-डू" इनपुट में बाद में उपयोग के लिए। आप antiCSRFToken . के उपयोग को भी नोटिस कर सकते हैं ! Blitz.js को किसी भी प्रकार के दुर्भावनापूर्ण अभिनेता को आपकी साइट को नुकसान पहुंचाने से रोकने के लिए कोई भी API रूट प्राप्त करते समय इन टोकन के उपयोग की आवश्यकता होती है। मेरे विचार से यह अच्छा है!

हम वेबसाइट पर अपने डेटा को संभालने के लिए तीन मुख्य कार्यों का उपयोग करते हैं। ये तीन हैं:

  • handleAddTodo
  • handleRemoveTodo
  • fetchTodos

हम fetchTodos . कहते हैं जैसे ही पृष्ठ लोड होता है, सभी टू-डॉस को लोड करने के लिए जिसे उपयोगकर्ता को अभी भी पूरा करने की आवश्यकता होती है। जब कोई उपयोगकर्ता टू-डू को हटाता है या जोड़ता है, तो हम fetchTodos . कहते हैं वेबसाइट पर उस बदलाव को फिर से दिखाने के लिए!

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

यदि कोई उपयोगकर्ता लॉग इन नहीं है, तो उपयोगकर्ता को इस पृष्ठ को देखने से पहले वेबसाइट पर लॉगिन करने के लिए प्रेरित किया जाएगा।

यदि आपके पास वेबसाइट पर पहले से कोई सत्र नहीं है तो आप साइन अप या लॉग इन कर सकते हैं। याद रखें, आप अपने टू-डॉस को एक खाते के बिना स्टोर नहीं कर सकते हैं, और सभी एपीआई रूटों के लिए आपको AntiCSRFToken के साथ प्रमाणित होना आवश्यक है। !

लेकिन रुकिए, एक और महत्वपूर्ण कदम! हमें पेज को एक्सपोर्ट करना है!

const Home: BlitzPage = () => {
  return (
    <div className="flex flex-col min-h-screen items-center justify-center">
      <main>
        <div className="my-4">
          <Suspense fallback="Loading...">
            <Main />
          </Suspense>
        </div>
      </main>
    </div>
  );
};

Home.suppressFirstRenderFlicker = true;
Home.getLayout = (page) => <Layout title="Home">{page}</Layout>;

export default Home;

जैसा कि आप ऊपर देख सकते हैं, Blitz.js एक दृष्टिकोण का उपयोग करता है जो नेक्स्ट से थोड़ा अलग है, लेकिन अभी के लिए इसके मूल में दृष्टिकोण समान है। हम Suspense . का उपयोग करते हैं जिसे हमने पहले एक उपयोगकर्ता को दिखाने के लिए आयात किया था कि ऐप लोड हो रहा है, और फिर हम अपना </Main> दिखाते हैं घटक लोड होने के बाद!

अपने परिवर्तनों को प्रभाव में देखने के लिए, इसे अपने कंसोल में एक बार और चलाएं, और ब्राउज़र में अपने ऐप पर नेविगेट करें।

blitz dev

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

Blitz.js और Redis . के साथ टू-डू सूची बनाना

आप एक टू-डू को उसके आगे वाले बॉक्स पर क्लिक करके हटा सकते हैं, जो कि removeTodo है फ़ंक्शन 😉 के लिए है।

बधाई हो!

मुझे आशा है कि आपने इस ब्लॉग पोस्ट को पढ़कर कुछ नया सीखा है, और यदि आपने नहीं किया है, तो याद रखें कि आपके कौशल को बढ़ाने में कोई हर्ज नहीं है! Blitz.js, Next.js से ध्यान हटा रहा है, इसलिए भविष्य में यह पूरी तरह से अलग ढांचा हो सकता है, लेकिन यहां उनकी वेबसाइट पर बने रहें!

परियोजना स्रोत :गिटहब लिंक

कार्य प्रदर्शन: डेमो लिंक

प्रतिक्रिया है? ट्विटर पर @upstash का अनुसरण करना सुनिश्चित करें, और डिस्कॉर्ड सर्वर से जुड़ें!


  1. रेडिस के साथ रीमिक्स TODO ऐप

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

  1. एज कैशिंग के साथ 5 एमएस ग्लोबल रेडिस लेटेंसी

    जब डेटाबेस और क्लाइंट एक ही क्षेत्र में हों, तो Redis के साथ 1 ms लेटेंसी आसान होती है। लेकिन अगर आप चाहते हैं कि ग्राहकों को विश्व स्तर पर वितरित किया जाए तो विलंबता 100 एमएस से अधिक हो जाती है। हमने इसे दूर करने के लिए एज कैशिंग का निर्माण किया। एज कैशिंग एज कैशिंग के साथ, सीडीएन की तरह, आरईएसटी

  1. रेडिस @ एज विद क्लाउडफ्लेयर वर्कर्स

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