বাংলা

Next.js মিডলওয়্যার সম্পর্কে জানুন, যা ইনকামিং রিকোয়েস্ট আটকানো এবং পরিবর্তন করার একটি শক্তিশালী ফিচার। ব্যবহারিক উদাহরণ সহ প্রমাণীকরণ, অনুমোদন, পুনঃনির্দেশ এবং A/B টেস্টিং কীভাবে বাস্তবায়ন করবেন তা শিখুন।

Next.js মিডলওয়্যার: ডাইনামিক অ্যাপ্লিকেশনের জন্য রিকোয়েস্ট ইন্টারসেপশনে দক্ষতা অর্জন

Next.js মিডলওয়্যার আপনার রুটগুলোতে পৌঁছানোর আগে ইনকামিং রিকোয়েস্ট আটকানো এবং পরিবর্তন করার একটি নমনীয় ও শক্তিশালী উপায় প্রদান করে। এই ক্ষমতা আপনাকে প্রমাণীকরণ এবং অনুমোদন থেকে শুরু করে পুনঃনির্দেশ এবং A/B টেস্টিং পর্যন্ত বিভিন্ন ধরণের ফিচার প্রয়োগ করতে সক্ষম করে, এবং একই সাথে পারফরম্যান্স অপ্টিমাইজ করে। এই বিস্তারিত গাইড আপনাকে Next.js মিডলওয়্যারের মূল ধারণাগুলি সম্পর্কে জানাবে এবং কীভাবে এটি কার্যকরভাবে ব্যবহার করা যায় তা প্রদর্শন করবে।

Next.js মিডলওয়্যার কী?

Next.js-এ মিডলওয়্যার হলো একটি ফাংশন যা একটি রিকোয়েস্ট সম্পন্ন হওয়ার আগে চলে। এটি আপনাকে নিম্নলিখিত কাজগুলো করতে দেয়:

মিডলওয়্যার ফাংশনগুলি আপনার প্রজেক্টের রুটে middleware.ts (অথবা middleware.js) ফাইলে সংজ্ঞায়িত করা হয়। এগুলি আপনার অ্যাপ্লিকেশনের প্রতিটি রুটের জন্য, অথবা কনফিগারযোগ্য ম্যাচারের উপর ভিত্তি করে নির্দিষ্ট রুটের জন্য কার্যকর করা হয়।

মূল ধারণা এবং সুবিধা

Request অবজেক্ট

request অবজেক্টটি ইনকামিং রিকোয়েস্ট সম্পর্কে তথ্য প্রদান করে, যার মধ্যে রয়েছে:

Response অবজেক্ট

মিডলওয়্যার ফাংশনগুলো রিকোয়েস্টের ফলাফল নিয়ন্ত্রণ করতে একটি Response অবজেক্ট রিটার্ন করে। আপনি নিম্নলিখিত প্রতিক্রিয়াগুলি ব্যবহার করতে পারেন:

Matchers

ম্যাচার আপনাকে নির্দিষ্ট করতে দেয় যে আপনার মিডলওয়্যার কোন রুটগুলিতে প্রয়োগ করা উচিত। আপনি রেগুলার এক্সপ্রেশন বা পাথ প্যাটার্ন ব্যবহার করে ম্যাচার নির্ধারণ করতে পারেন। এটি নিশ্চিত করে যে আপনার মিডলওয়্যার শুধুমাত্র প্রয়োজনের সময় চলে, যা পারফরম্যান্স উন্নত করে এবং ওভারহেড কমায়।

Edge Runtime

Next.js মিডলওয়্যার এজ রানটাইমে চলে, যা একটি লাইটওয়েট জাভাস্ক্রিপ্ট রানটাইম এনভায়রনমেন্ট যা আপনার ব্যবহারকারীদের কাছাকাছি স্থাপন করা যেতে পারে। এই নৈকট্য ল্যাটেন্সি কমিয়ে দেয় এবং আপনার অ্যাপ্লিকেশনের সামগ্রিক পারফরম্যান্স উন্নত করে, বিশেষ করে বিশ্বব্যাপী বিতরণ করা ব্যবহারকারীদের জন্য। এজ রানটাইম Vercel-এর এজ নেটওয়ার্ক এবং অন্যান্য সামঞ্জস্যপূর্ণ প্ল্যাটফর্মে উপলব্ধ। এজ রানটাইমের কিছু সীমাবদ্ধতা রয়েছে, বিশেষ করে Node.js API-এর ব্যবহারে।

ব্যবহারিক উদাহরণ: মিডলওয়্যার ফিচার বাস্তবায়ন

১. প্রমাণীকরণ (Authentication)

প্রমাণীকরণ মিডলওয়্যার সেইসব রুটগুলিকে সুরক্ষিত করতে ব্যবহার করা যেতে পারে যেখানে ব্যবহারকারীদের লগ ইন করা প্রয়োজন। কুকি ব্যবহার করে কীভাবে প্রমাণীকরণ বাস্তবায়ন করা যায় তার একটি উদাহরণ এখানে দেওয়া হলো:


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
 const token = request.cookies.get('auth_token');

 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url))
 }

 return NextResponse.next()
}

export const config = {
 matcher: ['/dashboard/:path*'],
}

এই মিডলওয়্যারটি একটি auth_token কুকির উপস্থিতি পরীক্ষা করে। যদি কুকিটি না পাওয়া যায়, ব্যবহারকারীকে /login পেজে পুনঃনির্দেশ করা হয়। config.matcher নির্দিষ্ট করে যে এই মিডলওয়্যারটি শুধুমাত্র /dashboard-এর অধীনে থাকা রুটগুলির জন্য চালানো উচিত।

বৈশ্বিক দৃষ্টিকোণ: বিভিন্ন অঞ্চলের ব্যবহারকারীদের জন্য বিভিন্ন প্রমাণীকরণ পদ্ধতি (যেমন, OAuth, JWT) সমর্থন করার জন্য প্রমাণীকরণ লজিককে অভিযোজিত করুন এবং বিভিন্ন আইডেন্টিটি প্রোভাইডারের (যেমন, Google, Facebook, Azure AD) সাথে একীভূত করুন।

২. অনুমোদন (Authorization)

অনুমোদন মিডলওয়্যার ব্যবহারকারীর ভূমিকা বা অনুমতির উপর ভিত্তি করে রিসোর্সে অ্যাক্সেস নিয়ন্ত্রণ করতে ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, আপনার একটি অ্যাডমিন ড্যাশবোর্ড থাকতে পারে যা শুধুমাত্র নির্দিষ্ট ব্যবহারকারীরা অ্যাক্সেস করতে পারে।


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
 const token = request.cookies.get('auth_token');

 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url))
 }

 // উদাহরণ: একটি API থেকে ব্যবহারকারীর ভূমিকা আনুন (আপনার আসল লজিক দিয়ে প্রতিস্থাপন করুন)
 const userResponse = await fetch('https://api.example.com/userinfo', {
 headers: {
 Authorization: `Bearer ${token}`,
 },
 });
 const userData = await userResponse.json();

 if (userData.role !== 'admin') {
 return NextResponse.redirect(new URL('/unauthorized', request.url))
 }

 return NextResponse.next()
}

export const config = {
 matcher: ['/admin/:path*'],
}

এই মিডলওয়্যারটি ব্যবহারকারীর ভূমিকা পুনরুদ্ধার করে এবং তাদের admin ভূমিকা আছে কিনা তা পরীক্ষা করে। যদি না থাকে, তাদের একটি /unauthorized পেজে পুনঃনির্দেশ করা হয়। এই উদাহরণটি একটি প্লেসহোল্ডার API এন্ডপয়েন্ট ব্যবহার করে। `https://api.example.com/userinfo`-কে আপনার আসল প্রমাণীকরণ সার্ভার এন্ডপয়েন্ট দিয়ে প্রতিস্থাপন করুন।

বৈশ্বিক দৃষ্টিকোণ: ব্যবহারকারীর ডেটা পরিচালনা করার সময় ডেটা গোপনীয়তা প্রবিধান (যেমন, GDPR, CCPA) সম্পর্কে সচেতন থাকুন। সংবেদনশীল তথ্য রক্ষা করতে এবং স্থানীয় আইনের সাথে সম্মতি নিশ্চিত করতে উপযুক্ত নিরাপত্তা ব্যবস্থা প্রয়োগ করুন।

৩. পুনঃনির্দেশ (Redirection)

পুনঃনির্দেশ মিডলওয়্যার ব্যবহারকারীদের তাদের অবস্থান, ভাষা বা অন্যান্য মানদণ্ডের উপর ভিত্তি করে পুনঃনির্দেশ করতে ব্যবহার করা যেতে পারে। উদাহরণস্বরূপ, আপনি ব্যবহারকারীদের তাদের IP ঠিকানার উপর ভিত্তি করে আপনার ওয়েবসাইটের একটি স্থানীয় সংস্করণে পুনঃনির্দেশ করতে পারেন।


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
 const country = request.geo?.country || 'US'; // ভূ-অবস্থান ব্যর্থ হলে ডিফল্ট US

 if (country === 'DE') {
 return NextResponse.redirect(new URL('/de', request.url))
 }

 if (country === 'FR') {
 return NextResponse.redirect(new URL('/fr', request.url))
 }

 return NextResponse.next()
}

export const config = {
 matcher: ['/'],
}

এই মিডলওয়্যারটি ব্যবহারকারীর IP ঠিকানার উপর ভিত্তি করে তাদের দেশ পরীক্ষা করে এবং তাদের ওয়েবসাইটের উপযুক্ত স্থানীয় সংস্করণে (জার্মানির জন্য /de, ফ্রান্সের জন্য /fr) পুনঃনির্দেশ করে। যদি ভূ-অবস্থান ব্যর্থ হয়, এটি US সংস্করণে ডিফল্ট হয়। মনে রাখবেন যে এটি geo প্রপার্টি উপলব্ধ হওয়ার উপর নির্ভর করে (যেমন, Vercel-এ স্থাপন করা হলে)।

বৈশ্বিক দৃষ্টিকোণ: আপনার ওয়েবসাইট একাধিক ভাষা এবং মুদ্রা সমর্থন করে তা নিশ্চিত করুন। ব্যবহারকারীদের তাদের পছন্দের ভাষা বা অঞ্চল ম্যানুয়ালি নির্বাচন করার বিকল্প দিন। প্রতিটি অঞ্চলের জন্য উপযুক্ত তারিখ এবং সময় বিন্যাস ব্যবহার করুন।

৪. A/B টেস্টিং

মিডলওয়্যার ব্যবহারকারীদের একটি পেজের বিভিন্ন ভ্যারিয়েন্টে এলোমেলোভাবে বরাদ্দ করে এবং তাদের আচরণ ট্র্যাক করে A/B টেস্টিং বাস্তবায়ন করতে ব্যবহার করা যেতে পারে। এখানে একটি সরলীকৃত উদাহরণ দেওয়া হলো:


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

function getRandomVariant() {
 return Math.random() < 0.5 ? 'A' : 'B';
}

export function middleware(request: NextRequest) {
 let variant = request.cookies.get('variant')?.value;

 if (!variant) {
 variant = getRandomVariant();
 const response = NextResponse.next();
 response.cookies.set('variant', variant);
 return response;
 }

 if (variant === 'B') {
 return NextResponse.rewrite(new URL('/variant-b', request.url));
 }

 return NextResponse.next();
}

export const config = {
 matcher: ['/'],
}

এই মিডলওয়্যারটি ব্যবহারকারীদের 'A' বা 'B' ভ্যারিয়েন্টে বরাদ্দ করে। যদি কোনো ব্যবহারকারীর ইতিমধ্যে একটি variant কুকি না থাকে, তাহলে একটি এলোমেলোভাবে বরাদ্দ করা হয় এবং সেট করা হয়। 'B' ভ্যারিয়েন্টে বরাদ্দ করা ব্যবহারকারীদের /variant-b পেজে রিরাইট করা হয়। কোনটি বেশি কার্যকর তা নির্ধারণ করতে আপনি প্রতিটি ভ্যারিয়েন্টের পারফরম্যান্স ট্র্যাক করবেন।

বৈশ্বিক দৃষ্টিকোণ: A/B পরীক্ষা ডিজাইন করার সময় সাংস্কৃতিক পার্থক্য বিবেচনা করুন। যা এক অঞ্চলে ভাল কাজ করে তা অন্য অঞ্চলের ব্যবহারকারীদের সাথে অনুরণিত নাও হতে পারে। আপনার A/B টেস্টিং প্ল্যাটফর্ম বিভিন্ন অঞ্চলের গোপনীয়তা প্রবিধানের সাথে সঙ্গতিপূর্ণ কিনা তা নিশ্চিত করুন।

৫. ফিচার ফ্ল্যাগ (Feature Flags)

ফিচার ফ্ল্যাগ আপনাকে নতুন কোড স্থাপন না করেই আপনার অ্যাপ্লিকেশনের ফিচারগুলি সক্ষম বা অক্ষম করতে দেয়। মিডলওয়্যার ব্যবহার করে নির্ধারণ করা যেতে পারে যে একজন ব্যবহারকারীর তাদের ইউজার আইডি, অবস্থান বা অন্যান্য মানদণ্ডের উপর ভিত্তি করে একটি নির্দিষ্ট ফিচারে অ্যাক্সেস থাকা উচিত কিনা।


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
 // উদাহরণ: একটি API থেকে ফিচার ফ্ল্যাগ আনুন
 const featureFlagsResponse = await fetch('https://api.example.com/featureflags', {
 headers: {
 'X-User-Id': 'user123',
 },
 });
 const featureFlags = await featureFlagsResponse.json();

 if (featureFlags.new_feature_enabled) {
 // নতুন ফিচারটি সক্রিয় করুন
 return NextResponse.next();
 } else {
 // নতুন ফিচারটি নিষ্ক্রিয় করুন (যেমন, একটি বিকল্প পেজে পুনঃনির্দেশ করুন)
 return NextResponse.redirect(new URL('/alternative-page', request.url));
 }
}

export const config = {
 matcher: ['/new-feature'],
}

এই মিডলওয়্যারটি একটি API থেকে ফিচার ফ্ল্যাগ আনে এবং new_feature_enabled ফ্ল্যাগটি সেট করা আছে কিনা তা পরীক্ষা করে। যদি থাকে, ব্যবহারকারী /new-feature পেজ অ্যাক্সেস করতে পারে। অন্যথায়, তাদের একটি /alternative-page-এ পুনঃনির্দেশ করা হয়।

বৈশ্বিক দৃষ্টিকোণ: বিভিন্ন অঞ্চলের ব্যবহারকারীদের কাছে ধীরে ধীরে নতুন ফিচারগুলি রোল আউট করতে ফিচার ফ্ল্যাগ ব্যবহার করুন। এটি আপনাকে একটি বৃহত্তর দর্শকের কাছে ফিচারটি প্রকাশ করার আগে পারফরম্যান্স নিরীক্ষণ করতে এবং যেকোনো সমস্যা সমাধান করতে দেয়। এছাড়াও, আপনার ফিচার ফ্ল্যাগিং সিস্টেম বিশ্বব্যাপী স্কেল করে এবং ব্যবহারকারীর অবস্থান নির্বিশেষে সামঞ্জস্যপূর্ণ ফলাফল প্রদান করে তা নিশ্চিত করুন। ফিচার রোলআউটের জন্য আঞ্চলিক নিয়ন্ত্রক সীমাবদ্ধতা বিবেচনা করুন।

উন্নত কৌশল

চেইনিং মিডলওয়্যার (Chaining Middleware)

আপনি একটি রিকোয়েস্টের উপর একাধিক অপারেশন সম্পাদনের জন্য একাধিক মিডলওয়্যার ফাংশনকে একসাথে চেইন করতে পারেন। এটি জটিল লজিককে ছোট, আরও পরিচালনাযোগ্য মডিউলে বিভক্ত করার জন্য দরকারী হতে পারে।


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
 const response = NextResponse.next();

 // প্রথম মিডলওয়্যার ফাংশন
 const token = request.cookies.get('auth_token');
 if (!token) {
 return NextResponse.redirect(new URL('/login', request.url))
 }

 // দ্বিতীয় মিডলওয়্যার ফাংশন
 response.headers.set('x-middleware-custom', 'value');

 return response;
}

export const config = {
 matcher: ['/dashboard/:path*'],
}

এই উদাহরণটি একটিতে দুটি মিডলওয়্যার দেখায়। প্রথমটি প্রমাণীকরণ সম্পাদন করে এবং দ্বিতীয়টি একটি কাস্টম হেডার সেট করে।

এনভায়রনমেন্ট ভেরিয়েবল ব্যবহার করা

API কী এবং ডাটাবেস ক্রেডেনশিয়ালের মতো সংবেদনশীল তথ্য আপনার মিডলওয়্যার ফাংশনে হার্ডকোড করার পরিবর্তে এনভায়রনমেন্ট ভেরিয়েবলে সংরক্ষণ করুন। এটি নিরাপত্তা উন্নত করে এবং আপনার অ্যাপ্লিকেশনের কনফিগারেশন পরিচালনা করা সহজ করে তোলে।


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

const API_KEY = process.env.API_KEY;

export async function middleware(request: NextRequest) {
 const response = await fetch('https://api.example.com/data', {
 headers: {
 'X-API-Key': API_KEY,
 },
 });

 // ...
}

export const config = {
 matcher: ['/data'],
}

এই উদাহরণে, API_KEY একটি এনভায়রনমেন্ট ভেরিয়েবল থেকে পুনরুদ্ধার করা হয়েছে।

ত্রুটি হ্যান্ডলিং (Error Handling)

আপনার অ্যাপ্লিকেশনকে অপ্রত্যাশিত ত্রুটি থেকে ক্র্যাশ হওয়া রোধ করতে আপনার মিডলওয়্যার ফাংশনগুলিতে শক্তিশালী ত্রুটি হ্যান্ডলিং প্রয়োগ করুন। ব্যতিক্রম ধরতে এবং যথাযথভাবে ত্রুটি লগ করতে try...catch ব্লক ব্যবহার করুন।


// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export async function middleware(request: NextRequest) {
 try {
 const response = await fetch('https://api.example.com/data');
 // ...
 } catch (error) {
 console.error('Error fetching data:', error);
 return NextResponse.error(); // অথবা একটি ত্রুটি পেজে পুনঃনির্দেশ করুন
 }
}

export const config = {
 matcher: ['/data'],
}

সেরা অনুশীলন (Best Practices)

সাধারণ সমস্যার সমাধান

উপসংহার

Next.js মিডলওয়্যার ডাইনামিক এবং ব্যক্তিগতকৃত ওয়েব অ্যাপ্লিকেশন তৈরির জন্য একটি শক্তিশালী টুল। রিকোয়েস্ট ইন্টারসেপশনে দক্ষতা অর্জনের মাধ্যমে, আপনি প্রমাণীকরণ এবং অনুমোদন থেকে শুরু করে পুনঃনির্দেশ এবং A/B টেস্টিং পর্যন্ত বিভিন্ন ফিচার বাস্তবায়ন করতে পারেন। এই গাইডে বর্ণিত সেরা অনুশীলনগুলি অনুসরণ করে, আপনি আপনার বিশ্বব্যাপী ব্যবহারকারী বেসের চাহিদা মেটাতে উচ্চ-পারফরম্যান্স, সুরক্ষিত এবং স্কেলেবল অ্যাপ্লিকেশন তৈরি করতে Next.js মিডলওয়্যার ব্যবহার করতে পারেন। আপনার Next.js প্রকল্পগুলিতে নতুন সম্ভাবনা আনলক করতে এবং ব্যতিক্রমী ব্যবহারকারীর অভিজ্ঞতা প্রদান করতে মিডলওয়্যারের শক্তিকে আলিঙ্গন করুন।