এই নিবন্ধে, আমরা একটি সার্ভারহীন Next.js ভিত্তিক TODO অ্যাপ্লিকেশন তৈরি করব। আমরা এটিকে ন্যূনতম করার জন্য আমাদের যথাসাধ্য চেষ্টা করব। এতে কোনো ডাটাবেস সংযোগ থাকবে না। এতে Next.js ছাড়া অন্য কোনো অতিরিক্ত নির্ভরতা থাকবে না। এতে কোনো বোতাম থাকবে না। এছাড়া, minimalism
শান্ত এবং পরিষ্কার, আমি এটি পছন্দ করি কারণ আমি একজন অলস বিকাশকারী :)
কেন আমরা ডাটাবেস সংযোগ এড়িয়ে চলি?
Next.js হল একটি আধুনিক ফ্রেমওয়ার্ক যা ফ্রন্ট-এন্ড ডেভেলপারদের সম্পূর্ণ স্ট্যাক অ্যাপ্লিকেশন ডেভেলপ করতে সক্ষম করে। Next.js ডেভেলপারদের জন্য ব্যাকএন্ড ডেভেলপমেন্টকে সহজ করার জন্য সার্ভারহীন ফাংশনগুলির একটি গুরুত্বপূর্ণ ভূমিকা রয়েছে। আপনি সম্ভবত জানেন, সার্ভারহীন ফাংশনগুলি তাদের রাষ্ট্রহীন প্রকৃতির কারণে ডাটাবেস সংযোগ পছন্দ করে না। সার্ভারহীন ফাংশনের ভিতরে ডাটাবেস সংযোগের সমস্যার উদাহরণ হিসাবে এখানে এবং এখানে দেখুন৷
REST হল একটি উত্তর
৷REST ক্লায়েন্ট এবং সার্ভারকে সেশনের তথ্য ছাড়াই যোগাযোগ করতে দেয়। এই রাষ্ট্রহীনতা এবং এর সরল প্রকৃতি RESTকে সার্ভারহীন পরিবেশের জন্য একটি নিখুঁত যোগাযোগ প্রোটোকল করে তোলে। আমরা REST এর সাথে Upstash Redis অ্যাক্সেস করব।
প্রজেক্ট স্ট্যাক
- ফ্রন্টএন্ড:Next.js
- ব্যাকএন্ড:Vercel ফাংশন
- ডাটাবেস:REST API সহ Upstash Redis
ডেমো দেখুন:https://nextjs-todo-zeta.vercel.app/
কোড দেখুন:https://github.com/upstash/examples/tree/master/nextjs-todo
প্রকল্প সেটআপ
একটি Next.js অ্যাপ তৈরি করুন:npx create-next-app
AWS-US-EAST-1 অঞ্চলে একটি Upstash Redis ডাটাবেস তৈরি করুন এবং REST URL এবং টোকেন কপি করুন।
প্রকল্পটি 3টি API এন্ডপয়েন্ট সহ একটি একক পৃষ্ঠার অ্যাপ্লিকেশন হবে:
- pages/api/list.js:TODO আইটেম তালিকাভুক্ত করে।
- পৃষ্ঠা/api/add.js:একটি TODO আইটেম যোগ করে।
- pages/api/remove.js:একটি TODO আইটেম সরিয়ে দেয়।
কোড
নিচের মত pages/api/list.js যোগ করুন:
export default async (req, res) => {
const token = "REPLACE_YOUR_TOKEN";
const url = "https://REPLACE_YOUR_ENDPOINT/lrange/todo/0/100?_token=" + token;
return fetch(url)
.then((r) => r.json())
.then((data) => {
let result = JSON.stringify(data.result);
return res.status(200).json(result);
});
};
নিচের মত পেজ/api/add.js যোগ করুন:
export default async (req, res) => {
if (!req.query.todo) {
return res.status(400).send("todo parameter required.");
}
let todo = encodeURI(req.query.todo);
const token = "REPLACE_YOUR_TOKEN";
const url =
"https://REPLACE_YOUR_ENDPOINT/lpush/todo/" + todo + "?_token=" + token;
return fetch(url)
.then((r) => r.json())
.then((data) => {
let result = JSON.stringify(data.result);
return res.status(200).json(result);
});
};
নিচের মত pages/api/remove.js যোগ করুন:
export default async (req, res) => {
if (!req.query.todo) {
return res.status(400).send("todo parameter required.");
}
let todo = encodeURI(req.query.todo);
const token = "REPLACE_YOUR_TOKEN";
const url =
"https://REPLACE_YOUR_ENDPOINT/lrem/todo/1/" + todo + "?_token=" + token;
return fetch(url)
.then((r) => r.json())
.then((data) => {
let result = JSON.stringify(data.result);
return res.status(200).json(result);
});
};
পেজ/index.js নিচের মত আপডেট করুন:
import Head from "next/head";
import Image from "next/image";
import styles from "../styles/Home.module.css";
import { useEffect, useState } from "react";
export default function Home() {
const [data, setData] = useState([]);
const [loading, setLoading] = useState(false);
const [todo, setTodo] = useState("");
let changeHandler = (event) => {
setTodo(event.target.value);
};
let addTodo = (event) => {
setLoading(true);
event.preventDefault();
fetch("/api/add?todo=" + todo)
.then((res) => res.json())
.then((data) => {
loadTodos();
});
};
let removeTodo = (rtodo) => {
setLoading(true);
fetch("/api/remove?todo=" + rtodo)
.then((res) => res.json())
.then((data) => {
loadTodos();
});
};
let loadTodos = () => {
console.log("load todos");
fetch("/api/list")
.then((res) => res.json())
.then((data) => {
setData(data);
setLoading(false);
});
};
useEffect(() => {
setLoading(true);
loadTodos();
}, []);
if (!data) return "Loading...";
return (
<div className={styles.container}>
<Head>
<title>Next.js TODO APP</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<div className={styles.grid}>
<h1 className={styles.title}>
TODO App with{" "}
<a href="https://blog.upstash.com/nextjs-todo">Next.js!</a>
<br />
<br />
</h1>
{loading ? (
<a href="#" className={styles.card}>
<img src="/loader.gif" />
</a>
) : (
<form className={styles.cardForm} onSubmit={addTodo}>
<input
className={styles.cardInput}
type="text"
name="todo"
onChange={changeHandler}
placeholder="Enter your exciting TODO item!"
/>
</form>
)}
{data.map((item) => (
<a
href="#"
onClick={() => removeTodo(item)}
className={styles.card}
>
<p>{item}</p>
</a>
))}
</div>
</main>
<footer className={styles.footer}>
<a
href="https://blog.upstash.com/nextjs-todo"
target="_blank"
rel="noopener noreferrer"
>
Powered by{" "}
<span className={styles.logo}>
<Image src="/logo.png" alt="Upstash Logo" width={87} height={25} />
</span>
</a>
</footer>
</div>
);
}
আপনি দেখতে পাচ্ছেন, এটি একটি মৌলিক প্রতিক্রিয়া অ্যাপ্লিকেশন যা হুক ব্যবহার করে। আমাদের কাছে 3টি পদ্ধতি রয়েছে যা API-এর সাথে ইন্টারঅ্যাক্ট করে:addTodo, removeTodo এবং loadTodos৷
এবং অবশেষে এখানে স্টাইল/Home.module.css ফাইল আপডেট করুন।
চালান এবং স্থাপন করুন
৷
npm run dev
দিয়ে স্থানীয়ভাবে আপনার প্রকল্প চালান . সবকিছু ঠিকঠাক থাকলে, আপনি vercel
চালিয়ে আপনার প্রকল্প স্থাপন করতে পারেন প্রকল্প ফোল্ডারে। Vercel আপনার API ফাংশনগুলির জন্য সার্ভারহীন ফাংশন তৈরি করবে। Vercel ফাংশনগুলির জন্য ডিফল্ট অঞ্চল হল US-EAST-1, সেই কারণে আমরা একই অঞ্চলে আমাদের ডাটাবেস তৈরি করেছি৷
নোট
৷- ভার্সেল এনভায়রনমেন্ট ভেরিয়েবলে ডাটাবেস টোকেন রাখা নিরাপদ।
- সার্ভারহীন ফাংশন এবং রেডিস ডাটাবেস একই অঞ্চলে রাখা কর্মক্ষমতার জন্য সবচেয়ে ভালো৷
- আমরা REST API এর পরিবর্তে Redis ক্লায়েন্ট ব্যবহার করতে পারি। কিন্তু আমি আগেই বলেছি, ডাটাবেস সংযোগগুলি সার্ভারহীন ফাংশনগুলির মধ্যে সমস্যা সৃষ্টি করতে পারে। এছাড়াও মনে রাখবেন যে আমরা Upstash REST API এবং নেটিভ API এর মধ্যে একটি বড় পারফরম্যান্স পার্থক্য দেখতে পাইনি।