সরাসরি পর্বে যান
পর্ব ৮৫ · ৯৩-এর মধ্যে · মডিউল ১৩

Stack বাছাই — MERN, Next.js, Django, Laravel আর সিদ্ধান্তের ছক

Choosing a Stack — MERN, Next.js, Django, Laravel and a Decision Matrix

Taught in Bangla, this lesson treats stack choice as trade-offs rather than rankings, asks seven deciding questions, gives honest strengths and limits of MERN, Next.js, Django, Laravel and others, applies hard constraints like hosting and team skills before scoring, starts with a monolith, uses boring technology and innovation tokens, builds a weighted decision matrix with sensitivity checks, reads framework health, and records decisions in ADRs.

এই পর্বে যা শিখবেন

  • কোন সাতটি প্রশ্ন stack-এর সিদ্ধান্ত আসলে ঠিক করে, আর একটি দৃশ্যপটে সেগুলোর উত্তর দেওয়া
  • MERN, Next.js, T3, Django, FastAPI, Laravel, Rails, Spring Boot, SvelteKit আর Nuxt-এর সৎ শক্তি আর সীমা
  • Monolith আগে, modular monolith, ডেটাবেস বাছাই আর innovation token-এর হিসাব
  • চারটি বাজারঘর-ধাঁচের দৃশ্যপটে ওজন দেওয়া সিদ্ধান্তের ছক আর তার সংবেদনশীলতা
  • Framework-এর স্বাস্থ্য পাবলিক তথ্য থেকে পড়া, ভুল বাছাইয়ের খরচ আর একটি পূর্ণ ADR

১ · র‍্যাঙ্কিং নয়, trade-off

কোর্সের ৮৪টি পর্বে আমরা বাজারঘর বানিয়েছি React, Express, Prisma আর Next.js দিয়ে, আর মডিউল ১০-এ একই দোকানের টুকরো দেখেছি Vue, Svelte, Django, FastAPI, Laravel, Spring Boot আর Rails-এ। এখন আসল প্রশ্ন: নতুন একটি প্রজেক্ট এলে কোনটি বাছবেন? Facebook গ্রুপে প্রশ্নটি প্রায়ই আসে “২০২৬ সালে কোন stack সেরা?” রূপে। উত্তরটি হতাশাজনক শোনালেও সৎ: প্রশ্নটিই অসম্পূর্ণ।

ঢাকায় মিরপুর থেকে মতিঝিল যাবেন। রিকশা, বাস, CNG, মেট্রো রেল, নাকি মোটরসাইকেল? কোনটি “সেরা”, তা নির্ভর করে কত টাকা আছে, সাথে কত মালপত্র, কতটা তাড়া, বৃষ্টি হচ্ছে কি না, আর আপনি নিজে চালাতে জানেন কি না। মেট্রো দ্রুত, কিন্তু স্টেশন থেকে দূরের গলিতে নেবে না; রিকশা গলিতে ঢোকে, কিন্তু ২০ কিলোমিটারে ক্লান্ত। Stack-ও তেমনি। প্রতিটি কিছু পথে চমৎকার, কিছু পথে অচল।

Tech stack মানে একটি অ্যাপ চালাতে যে প্রযুক্তিগুলো একসাথে বসে: frontend framework, backend framework, ভাষা, ORM, ডেটাবেস, আর কোথায় চলবে। একটি stack বাছাই মানে আসলে কয়েকটি ছোট সিদ্ধান্তের একটি গুচ্ছ, আর প্রতিটির দাম ভিন্ন।

  • বদলানো সহজ: CSS-এর পদ্ধতি, state library, test runner. ভুল হলে কয়েক দিনে বদলানো যায়।
  • বদলানো মাঝারি কঠিন: frontend framework, ORM. কয়েক সপ্তাহ থেকে কয়েক মাস।
  • বদলানো খুব কঠিন: backend-এর ভাষা, ডেটাবেসের ধরন, ডেটার মডেল, আর hosting-এর এমন সেবা যার ওপর অনেক কোড নির্ভর করে। এগুলো প্রায় দরজার তালার মতো, একবার লাগালে খোলা ঝামেলার।

Jeff Bezos-এর শেয়ারহোল্ডার চিঠির “একমুখী দরজা” আর “দুমুখী দরজা”-র ভাগ এখানে প্রায়ই উদ্ধৃত হয়: যে সিদ্ধান্ত ফেরানো যায়, তা দ্রুত নিন; যা ফেরানো কঠিন, তাতে সময় দিন। এই পর্বের কৌশলগুলো, প্রশ্নের তালিকা, কঠিন শর্তের ছাঁকনি, ওজন দেওয়া ছক আর ADR, মূলত একমুখী দরজাগুলোর জন্য।

সিদ্ধান্তের পাঁচ ধাপের ছাঁকনি

Questions → hard constraints → weighted matrix → sensitivity → decision record

Stack বাছাইয়ের ফানেল ১. সাতটি প্রশ্ন দল, নিয়োগ, পণ্য, SEO, hosting, সময়, রক্ষণাবেক্ষণ ২. কঠিন শর্তের ছাঁকনি যা চালানো যাবে না, তা বাদ ৩. ওজন দেওয়া ছক স্কোর × ওজন, যোগফলে ক্রম ৪. সংবেদনশীলতা বিজয়ী কতটা মজবুত? ৫. ADR সিদ্ধান্ত + কবে আবার ডান দিকের দাগ: শর্ত বদলালে আবার ধাপ ১ থেকে
ছবি ৮৫.১ — প্রতিটি ধাপ প্রার্থীর সংখ্যা কমায়। খেয়াল করুন, স্কোর দেওয়ার আগেই ছাঁকনি; আর শেষ ধাপে শুধু “কী বাছলাম” নয়, “কোন শর্তে আবার ভাবব” লেখা থাকে।

Stack-এর নাম দেওয়ার রীতি পুরোনো। LAMP (Linux, Apache, MySQL, PHP বা Perl) শব্দটি ১৯৯০-এর দশকের শেষ দিকে চালু হয় বলে সাধারণত বলা হয়। Rails আসে ২০০৪ সালে (David Heinemeier Hansson), Django ২০০৫ সালে, Laravel ২০১১ সালে (Taylor Otwell). MEAN (MongoDB, Express, Angular, Node) নামটি ২০১৩ সালের দিকে MongoDB-র একটি ব্লগ লেখায় জনপ্রিয় হয় বলে জানা যায়; পরে Angular-এর জায়গায় React বসিয়ে MERN, Vue বসিয়ে MEVN. Spring Boot আসে ২০১৪ সালে, Next.js ২০১৬ সালে, আর TypeScript, tRPC, Prisma আর Next.js মিলিয়ে T3 stack-এর ধারণা ২০২২ সালের দিকে create-t3-app নামের টুলের মাধ্যমে ছড়ায়। নামের জনপ্রিয়তা কোনো প্রকল্পের জন্য সঠিকতার প্রমাণ নয়।

২ · যে সাতটি প্রশ্ন সিদ্ধান্ত ঠিক করে

কোন framework-এ “বেশি feature” আছে, তা প্রায় কখনো সিদ্ধান্ত ঠিক করে না; আধুনিক বড় framework-গুলো মোটামুটি সব কাজ পারে। সিদ্ধান্ত ঠিক করে আপনার পরিস্থিতি। সাতটি প্রশ্ন লিখে উত্তর দিন, তারপর তবে framework-এর নাম ভাবুন।

  1. দল কী জানে? যাঁরা কোড লিখবেন আর রাত দুটোয় bug সারাবেন, তাঁরা কোন ভাষায় আর কোন framework-এ আগে production চালিয়েছেন? পরিচিত stack-এ একজন মাঝারি ডেভেলপার প্রায়ই অপরিচিত “আধুনিক” stack-এ একজন দক্ষ ডেভেলপারের চেয়ে দ্রুত নিরাপদ কোড দেন।
  2. নিয়োগের পুকুর কেমন? দল বড় করতে হলে স্থানীয়ভাবে বা দূর থেকে কোন stack-এর মানুষ পাওয়া সহজ। বাংলাদেশে PHP আর Laravel, JavaScript আর React, আর Python-এর ডেভেলপার খুঁজে পাওয়া সাধারণত সহজ বলে অনেকের অভিজ্ঞতা; Rails বা Elixir-এর মানুষ তুলনায় কম বলেই মনে হয়। কিন্তু এর কোনো নির্ভরযোগ্য সংখ্যা আমাদের কাছে নেই। নিজের শহরে চাকরির বিজ্ঞাপন আর পরিচিত মহলে খোঁজ নিয়ে যাচাই করুন।
  3. পণ্যটি কোন ধরনের? তথ্যের সাইট (ক্যাটালগ, ব্লগ), দোকান (cart, checkout, payment), ড্যাশবোর্ড (login-এর পেছনে টেবিল আর চার্ট), real-time অ্যাপ (chat, live bid, লাইভ ট্র্যাকিং), নাকি শুধু mobile অ্যাপের জন্য API. প্রতিটির চাপ আলাদা জায়গায়।
  4. SEO কতটা জরুরি? Google থেকে ক্রেতা আসা যদি ব্যবসার প্রাণ হয়, তবে server-এ HTML তৈরি করে এমন stack (SSR বা SSG) প্রায় বাধ্যতামূলক। Login-এর পেছনের ড্যাশবোর্ডে SEO প্রায় শূন্য গুরুত্বের; সেখানে একটি SPA পুরোপুরি ঠিক আছে। Rendering-এর মানচিত্র পর্ব ৩-এ, SEO-র কাজ পর্ব ৫৮-এ।
  5. বাজেট আর hosting কী আছে? বছরে একবার টাকায় বিল দেওয়া shared hosting, নিজে চালানো একটি VPS, নাকি একটি PaaS? চার জায়গার সীমা পর্ব ৮২-এ বিস্তারিত; এখানে শুধু মনে রাখুন, hosting প্রায়ই stack-কে বাদ দেয়, উল্টোটা নয়।
  6. বাজারে আসতে কত সময়? Time to market ছয় সপ্তাহ হলে admin panel, auth আর form নিজে বানানোর সময় নেই; তৈরি জিনিস (batteries included) বেশি মূল্যবান।
  7. পাঁচ বছর কে দেখবে? প্রজেক্ট হাতবদল হবে কি না, রক্ষণাবেক্ষণ কে করবেন, framework-এর upgrade পথ কতটা মসৃণ। লম্বা জীবনের অ্যাপে “আজ দ্রুত” বনাম “পাঁচ বছরে শান্ত” প্রায়ই বিপরীত দিকে টানে।

এবার একটি দৃশ্যপটে প্রশ্নগুলোর উত্তর ধাপে ধাপে দেখুন। দৃশ্যপট A: পুরান ঢাকার একটি মুদি দোকানের মালিক বাজারঘর-ধাঁচের একটি ছোট অনলাইন দোকান চান।

প্রশ্ন আর উত্তর
প্রশ্ন
উত্তর
যা বাদ পড়ল
টিকে আছে
  1. দল। একজন মানুষই সব করবেন, আর তিনি Laravel জানেন। এটি সবচেয়ে ভারী তথ্য, কারণ অন্য stack মানে তাঁকে আগে শিখতে হবে, ঈদের আগে সেই সময় নেই। তবে এখনই কিছু বাদ দিচ্ছি না; শুধু নোট রাখছি।
  2. নিয়োগ। মালিক মনে করেন পরে আরেকজন লাগলে PHP-র মানুষ পাওয়া সহজ হবে। এটি অনুমান, সংখ্যা নয়; তাই ওজনে ব্যবহার করব, কিন্তু একা এর ওপর সিদ্ধান্ত নেব না।
  3. পণ্য। সাধারণ দোকান: ক্যাটালগ, cart, cash on delivery. Live chat বা নিলাম নেই, তাই real-time-এর জন্য আলাদা ক্ষমতা লাগবে না। এই উত্তর অনেক stack-এর বিশেষ সুবিধাকে অপ্রাসঙ্গিক করে দেয়।
  4. SEO. এলাকার ক্রেতা “পুরান ঢাকা চাল ডেলিভারি” লিখে খুঁজবেন। Server থেকে পূর্ণ HTML দরকার, তাই শুধু browser-এ render হওয়া SPA দুর্বল প্রার্থী।
  5. Hosting. এখানেই বড় ছাঁকনি। দোকানের আগে থেকেই একটি cPanel প্যাকেজ আছে, যেখানে PHP আর MySQL চলে, Node বা Python অ্যাপের সুবিধা নেই। তাই Node বা Python server লাগে এমন সব stack বাদ। টিকে রইল Laravel আর Next.js-এর static export, যদিও static export-এ cart আর অর্ডারের জন্য বাইরের API লাগবে।
  6. সময়। ছয় সপ্তাহে login, admin আর অর্ডারের তালিকা নিজে লেখার সময় নেই। Laravel-এর starter kit আর তৈরি auth (পর্ব ৭০) এখানে সুবিধা দেয়; static export-এর পথে বাইরের API আলাদা বানাতে হতো।
  7. পাঁচ বছর। একই ফ্রিল্যান্সার বছরে কয়েকবার দেখবেন। পরিচিত, স্থিতিশীল stack এখানে জেতে। ফল: Laravel + Blade + MySQL, shared hosting-এ। কোনো ছক ছাড়াই উত্তর প্রায় স্পষ্ট; ছক তখনই লাগে, যখন একাধিক প্রার্থী টিকে থাকে।

মূল কথা

প্রশ্নের উত্তর লেখার সময় framework-এর নাম না লিখে পরিস্থিতি লিখুন: “একজন ফ্রিল্যান্সার PHP জানেন”, “hosting-এ Node নেই”। নাম আগে লিখলে বাকি উত্তরগুলো অজান্তেই সেই নামের পক্ষে সাজানো হয়ে যায়।

৩ · পরিচিত stack-গুলো — সৎ শক্তি আর সীমা

প্রতিটি stack এই কোর্সে কোথাও না কোথাও শেখানো হয়েছে। এখানে আবার শেখাচ্ছি না; শুধু পাশাপাশি রাখছি, যাতে বাছাইয়ের সময় এক নজরে দেখা যায়। “সীমা” কলামটি সমালোচনা নয়, দাম; প্রতিটি শক্তির পাশেই একটি দাম থাকে।

Stackযেখানে শক্তিশালীযে দাম দিতে হয়কোথায় শেখানো
MERN / MEVN: React বা Vue + Express + Node, MongoDB বা PostgreSQLএক ভাষা (JavaScript বা TypeScript) দুই দিকে; Express-এর ছোট, নমনীয় কাঠামো; একই Node process-এ WebSocket সহজকাঠামো আপনি নিজে বানান: auth, validation, ফোল্ডারের গঠন। শুধু SPA হলে SEO দুর্বল। নামের “M” মানেই MongoDB নিতে হবে নামডিউল ৪ (পর্ব ২৫, পর্ব ২৯), React মডিউল ২–৩
Next.js + PrismaSSR, SSG আর ISR একই প্রজেক্টে; Server Component আর Server Action; SEO শক্তিশালী; বড় ecosystemধারণার সংখ্যা বেশি (কোন কোড কোথায় চলে, cache-এর স্তর); version বদলের সাথে API বদলায়; full SSR-এর জন্য Node server বা adapter লাগেমডিউল ৬ (পর্ব ৩৯), মডিউল ৮ (পর্ব ৫১)
T3-ধাঁচের typed stack: Next.js + tRPC + Prisma + TypeScriptDatabase থেকে UI পর্যন্ত এক টানা type; API-র চুক্তি ভাঙলে compile-এর সময়েই ধরা পড়েClient আর server দুটোই TypeScript হতে হবে; mobile বা অন্য ভাষার client-এর জন্য আলাদা REST বা OpenAPI লাগেপর্ব ৩৭
Django বা FastAPI + React বা HTMXDjango: তৈরি admin, ORM, auth; ডেটা আর Python-এর দলের জন্য স্বাভাবিক। FastAPI: async API, Pydantic, স্বয়ংক্রিয় docsReact যোগ করলে দুটি ভাষা, দুটি build. HTMX-এ জটিল client-side UI কঠিন। FastAPI-তে admin বা auth নিজে জোড়া লাগেপর্ব ৬৮, পর্ব ৬৯
Laravel + Blade, Livewire বা InertiaShared hosting-এর স্বাভাবিক বাসিন্দা; queue, mail, auth, migration সব তৈরি; Inertia দিয়ে React বা Vue পাতাওReal-time বা queue worker-এর জন্য সবসময় চলা process লাগে, যা shared hosting-এ প্রায়ই নেই; প্রতি বছর major versionপর্ব ৭০
Rails + HotwireConvention over configuration; ছোট দলে খুব দ্রুত CRUD অ্যাপ; server-rendered HTML-এর আধুনিক পথবাংলাদেশে Ruby-র মানুষ কম বলেই মনে হয় (সংখ্যা নেই); ভিন্ন ধাঁচের convention শিখতে সময়পর্ব ৭১
Spring Bootবড় প্রতিষ্ঠান, ব্যাংক বা টেলিকমের মতো জায়গায় পরিচিত; শক্ত type, পরিপক্ব tooling, দীর্ঘ সমর্থনJVM-এর মেমরি আর শুরুর সময় তুলনায় বেশি হতে পারে; ছোট প্রজেক্টে কাঠামো ভারী মনে হয়পর্ব ৭১
SvelteKit, NuxtNext.js-এর মতোই full-stack meta-framework, ভিন্ন দর্শনে: Svelte-এর compiler, Vue-র reactivity; অনেকের কাছে শেখা সহজEcosystem আর তৈরি component তুলনায় ছোট; নিয়োগের পুকুর ছোট হতে পারেপর্ব ৬৬, পর্ব ৬৭

দুটি জিনিস খেয়াল করুন। “এক ভাষা দুই দিকে” (MERN, Next.js, T3) ছোট দলে বাস্তব সুবিধা, কারণ type আর validation-এর schema ভাগ করা যায় (পর্ব ২১)। আর “batteries included” framework (Django, Laravel, Rails) সময় বাঁচায়, কিন্তু তাদের পথের বাইরে গেলে লড়াই করতে হয়। প্রতিটি “দাম” আপনার পরিস্থিতিতে প্রাসঙ্গিক কি না, সেটিই আসল প্রশ্ন।

সম্প্রদায়ে মতভেদ আছে। “Full-stack JavaScript নাকি আলাদা backend ভাষা?” প্রশ্নে অভিজ্ঞ মানুষেরাও দুই দিকে। একপক্ষের যুক্তি কম context switch আর ভাগ করা type; অন্যপক্ষের, Django বা Laravel-এর তৈরি কাঠামো Express-এর খালি পাতার চেয়ে কম ভুলের সুযোগ দেয়। দুটিই ঠিক; কোনটি জিতবে, তা দলের অভিজ্ঞতা ঠিক করে।

৪ · কঠিন শর্ত আগে — hosting আর দল

কিছু শর্ত “পছন্দ” নয়, “হয় অথবা না”। শুধু PHP চলে এমন hosting-এ Node server চলবে না, যত ভালো স্কোরই হোক। এগুলোকে বলে কঠিন শর্ত। নিয়ম সোজা: কঠিন শর্ত দিয়ে আগে ছাঁকুন, তারপর যারা টিকে থাকে শুধু তাদের স্কোর দিন। নইলে ছকে একটি অচল বিকল্প জিতে যেতে পারে, আর সবাই তখন hosting বদলানোর যুক্তি খুঁজতে শুরু করেন।

সাধারণ কঠিন শর্তগুলো: hosting কোন runtime চালায় (PHP, Node, Python), সবসময় চলা process রাখা যায় কি না (WebSocket আর queue worker-এর জন্য), ডেটা দেশের ভেতরে রাখার মতো চুক্তি বা নিয়ম আছে কি না, আর প্রতিষ্ঠানের নীতিতে কোনো ভাষা বা লাইসেন্স নিষেধ কি না। নিচের মডেলটি প্রথম দুটি শর্ত পরীক্ষা করে। কোন hosting-এ কী থাকে, তা পর্ব ৮২-এর সাধারণ চিত্র থেকে নেওয়া; আপনার hosting-এর আসল বিবরণ মিলিয়ে নিন।

// কঠিন শর্ত আগে: যে stack চালানোই যাবে না, তাকে স্কোর দেওয়ার মানে নেই
const stacks = [
  { name: 'Laravel + Blade', runtime: 'php' },
  { name: 'Next.js static export', runtime: null },
  { name: 'Next.js SSR + Prisma', runtime: 'node' },
  { name: 'MERN + Socket.IO', runtime: 'node', alwaysOn: true },
  { name: 'Django + HTMX', runtime: 'python' },
  { name: 'Laravel + Reverb chat', runtime: 'php', alwaysOn: true },
];
const hosts = {
  'shared, PHP only': { php: true },
  'shared + Node/Python app': { php: true, node: true, python: true },
  'VPS': { php: true, node: true, python: true, alwaysOn: true },
};
function fits(s, h) {
  if (s.runtime && !h[s.runtime]) return 'NO  (no ' + s.runtime + ' app)';
  if (s.alwaysOn && !h.alwaysOn) return 'NO  (needs always-on process)';
  return 'ok';
}
for (const [hn, h] of Object.entries(hosts)) {
  const ok = stacks.filter(s => fits(s, h) === 'ok').length;
  console.log(`== ${hn}: ${ok} of ${stacks.length} fit`);
  for (const s of stacks) console.log('   ' + s.name.padEnd(22) + fits(s, h));
}

আউটপুটের তিনটি অংশ: == shared, PHP only: 2 of 6 fit, যেখানে টেকে শুধু Laravel + Blade আর Next.js static export; Next.js SSR + Prisma NO (no node app), Django-র সারিতে NO (no python app), আর Laravel + Reverb chat NO (needs always-on process). Node বা Python অ্যাপের সুবিধাওয়ালা shared hosting-এ 4 of 6 fit: Next.js SSR আর Django ঢোকে, কিন্তু Socket.IO আর Reverb-এর chat তখনো বাদ, কারণ এমন সুবিধা সাধারণত অলস হলে process থামিয়ে দেয় (পর্ব ৮২)। VPS: 6 of 6 fit. খেয়াল করুন, Laravel একই ভাষায় থেকেও chat যোগ করলে PHP-only hosting থেকে বাদ পড়ে: কঠিন শর্ত stack-এর নামের ওপর নয়, কোন feature লাগবে তার ওপর নির্ভর করে। একটি সারি যোগ করে দেখুন: { name: 'FastAPI + React', runtime: 'python' } কোন hosting-এ টেকে?

দলও একটি কঠিন শর্ত হতে পারে

“দলে কেউ Python জানেন না, আর তিন মাসে পণ্য চাই” হলে Django বাস্তবে প্রায় কঠিন শর্তে বাদ। নিয়োগ বা প্রশিক্ষণের সময় থাকলে শর্তটি নরম হয়ে স্কোরে যায়। কোন শর্ত কঠিন আর কোনটি শুধু ওজন, তা লিখে আলাদা করাই এই ধাপের কাজ।

৫ · Monolith আগে, তারপর দেখা — আর ডেটাবেস বাছাই

Stack-এর পাশাপাশি আরেকটি একমুখী দরজা হলো অ্যাপটি এক টুকরো হবে, নাকি অনেক সেবায় ভাগ হবে। Monolith মানে পুরো অ্যাপ একটি deploy-যোগ্য একক; microservices মানে আলাদা আলাদা সেবা, প্রত্যেকে নিজে deploy হয়, network-এ কথা বলে। তত্ত্ব আর বড় পরিসরের নকশা System Design কোর্সের Monolith বনাম microservices পর্বে, আর architecture pattern-এর মানচিত্র পর্ব ৪-এ।

Martin Fowler ২০১৫ সালের “MonolithFirst” লেখায় একটি পর্যবেক্ষণ দেন, যা প্রায়ই উদ্ধৃত হয়: তাঁর দেখা সফল microservice-এর গল্পগুলোর বেশিরভাগ শুরু হয়েছিল একটি monolith থেকে, যা বড় হয়ে ভাঙা হয়েছে; আর একদম শুরু থেকে microservice দিয়ে বানানো প্রকল্পে তিনি বেশ সমস্যা দেখেছেন। কারণ শুরুতে সেবার সীমানা কোথায় টানা উচিত, তা জানা থাকে না।

মাঝের পথ: modular monolith

Modular monolith হলো একটি deploy, কিন্তু ভেতরে শক্ত দেয়াল। ক্যাটালগ, cart, অর্ডার আর chat আলাদা module; প্রত্যেকে অন্যের সাথে কথা বলে শুধু একটি ঘোষিত interface দিয়ে, অন্যের টেবিলে সরাসরি হাত দেয় না। পরে কোনো module-কে আলাদা সেবা বানাতে হলে দেয়াল আগে থেকেই টানা থাকে।

একটি deploy, চারটি module, শুধু interface দিয়ে যোগাযোগ

Modular monolith: one deployable unit, enforced module boundaries, one database with owned tables

Modular monolith-এর গঠন বাজারঘর অ্যাপ · একটি deploy catalog getProduct() cart addItem() orders placeOrder() chat পরে আলাদা হতে পারে PostgreSQL · একটি database প্রতিটি টেবিলের একজন মালিক module
ছবি ৮৫.২ — নীল তীরগুলো শুধু অন্য module-এর ঘোষিত function-এ যায়। orders যদি catalog-এর টেবিলে সরাসরি UPDATE চালায়, দেয়ালটি ভেঙে যায়; তখন module আলাদা করার দিন খরচ অনেক বাড়বে। ভেতরের স্তর (controller, service, repository) পর্ব ২৯-এ।

বাজারঘরের মতো একটি দোকানের জন্য বাস্তব পরামর্শ: একটি monolith দিয়ে শুরু করুন, ভেতরে module-এর দেয়াল রাখুন। সেবা আলাদা করুন তখনই, যখন একটি মাপা কারণ আছে: একটি অংশের ভিন্ন ধরনের চাপ (chat-এর হাজার খোলা সংযোগ), ভিন্ন deploy-এর ছন্দ, বা আলাদা দল। পর্ব ৮৭-এ ১০০ থেকে ১০ লাখ ব্যবহারকারীর পথে ঠিক কখন কী ভাঙে, তা ধাপে ধাপে আসবে।

ডেটাবেস: সাধারণ উত্তর PostgreSQL, কিন্তু সবসময় নয়

ডেটাবেস stack-এর সবচেয়ে কঠিন একমুখী দরজা, কারণ কোড বদলানো যায়, কিন্তু কোটি সারির ডেটা আর তার ওপর নির্ভর করা query বদলানো অনেক কঠিন। উপভাষার পার্থক্য DBMS কোর্সের SQL-এর উপভাষা পর্বে, আর SQL বনাম NoSQL-এর তত্ত্ব System Design-এ।

PostgreSQL: ডিফল্ট

Transaction, constraint, JSON কলাম, full-text search, extension, সব এক জায়গায়। Prisma, Django, Laravel, Rails সবাই ভালোভাবে সমর্থন করে। নতুন প্রজেক্টে কারণ না থাকলে এটিই নিরাপদ শুরু; এই কোর্সের বাজারঘরও এতে চলেছে।

বেশিরভাগ ওয়েব অ্যাপ

MySQL বা MariaDB

cPanel shared hosting-এ প্রায় সবসময় এটিই থাকে, আর Laravel বা WordPress-এর দলের কাছে পরিচিত। Hosting-এ শুধু এটি থাকলে, এটিই সঠিক উত্তর।

shared hosting, PHP-র দল

SQLite

একটি ফাইলে পুরো database, আলাদা server নেই। ছোট internal tool, prototype, বা একটি server-এ চলা কম লেখার অ্যাপে চমৎকার। অনেক যন্ত্র থেকে একসাথে লেখার চাপ এলে সীমায় পৌঁছায়।

prototype, ছোট internal tool

MongoDB

Document মডেল, schema নমনীয়। ডেটা যদি সত্যিই document-ধাঁচের হয় আর সম্পর্ক কম, তবে উপযুক্ত। দোকানের order, stock আর payment-এর মতো সম্পর্কে ভরা ডেটায় অনেক দল পরে relational database-এর অভাব টের পান। বিস্তারিত DBMS কোর্সে।

document-ধাঁচের ডেটা

“MERN-এ M আছে, তাই MongoDB” একটি সাধারণ ভুল যুক্তি। Stack-এর নাম একটি প্যাকেজের লেবেল, নিয়ম নয়। Express আর React-এর সাথে PostgreSQL আর Prisma চালানো একদম স্বাভাবিক, আর বাজারঘরের অর্ডার-stock-এর transaction (পর্ব ৪৩) relational database-এ সহজ।

৬ · একঘেয়ে প্রযুক্তি আর innovation token

Dan McKinley, যিনি Etsy-তে কাজ করেছেন, ২০১৫ সালের দিকে “Choose Boring Technology” নামে একটি প্রবন্ধ লেখেন, যা পরে একটি বক্তৃতা হিসেবেও ছড়ায়। তাঁর মূল ধারণা: একটি প্রতিষ্ঠানের হাতে অল্প কয়েকটি innovation token থাকে, শুরুতে মোটামুটি তিনটি, আর প্রতিটি নতুন বা অপরিচিত প্রযুক্তি একটি token খরচ করে। তিনি নিজেই বলেছেন হিসাবটি কাল্পনিক, একটি ভাবার উপায় মাত্র। Boring technology মানে খারাপ প্রযুক্তি নয়; মানে এমন প্রযুক্তি, যার ব্যর্থতার ধরন সবাই জানে।

বিয়ের রান্না ভাবুন। বাবুর্চি যদি কাচ্চি, রোস্ট, বোরহানি আর ফিরনি সব পরীক্ষিত রেসিপিতে করেন, আর শুধু একটি নতুন মিষ্টান্ন যোগ করেন, তবে সেই একটি ভুল হলেও অনুষ্ঠান বাঁচে। কিন্তু চারটিই নতুন রেসিপি হলে, প্রথমবার নতুন চুলায়, তখন কোনটি কেন নষ্ট হলো তাও বোঝা যাবে না। Token হলো এই “নতুন রেসিপির” সীমা।

পরিচিত প্রযুক্তির অজানা সমস্যা কম, কারণ হাজারো দল সেগুলো আগেই খুঁজে পেয়েছে আর উত্তর লিখে রেখেছে; নতুন প্রযুক্তিতে প্রতিটি সমস্যা আপনাকে প্রথমবার সমাধান করতে হয়। তাই token খরচ করুন সেখানে, যেখানে নতুনত্ব পণ্যের মূল সুবিধা দেয়।

নিচের খেলনা মডেলে একটি প্রস্তাবিত stack-এর হিসাব। দল আগে production-এ চালিয়েছে React, TypeScript, Express, PostgreSQL আর একটি Linux VPS. প্রস্তাবে নয়টি জিনিস, যার কয়েকটি পণ্যের মূল (core), কয়েকটি “থাকলে ভালো”।

// Innovation token-এর খেলনা হিসাব: দলের কাছে নতুন প্রতিটি জিনিস একটি token খরচ করে
const BUDGET = 3;
const known = new Set(['react', 'typescript', 'express', 'postgresql', 'linux vps']);
const proposal = [
  { tech: 'nextjs',     core: true  },  // দোকানের পাতা আর SEO
  { tech: 'react',      core: true  },
  { tech: 'typescript', core: true  },
  { tech: 'prisma',     core: true  },
  { tech: 'postgresql', core: true  },
  { tech: 'trpc',       core: false },
  { tech: 'mongodb',    core: false },  // PostgreSQL থাকতেই দ্বিতীয় database
  { tech: 'graphql',    core: false },
  { tech: 'kubernetes', core: false },
];
function check(list) {
  const spent = list.filter(p => !known.has(p.tech));
  console.log(`tokens ${spent.length}/${BUDGET}: ${spent.map(p => p.tech).join(', ')}`);
  return spent.length <= BUDGET;
}
console.log('first proposal');
if (!check(proposal)) {
  const trimmed = proposal.filter(p => p.core || known.has(p.tech));
  const dropped = proposal.filter(p => !trimmed.includes(p)).map(p => p.tech);
  console.log('over budget, drop non-core new items: ' + dropped.join(', '));
  console.log('second proposal');
  console.log(check(trimmed) ? 'within budget' : 'still over budget');
}

আউটপুট: tokens 6/3: nextjs, prisma, trpc, mongodb, graphql, kubernetes, অর্থাৎ বাজেটের দ্বিগুণ। তারপর over budget, drop non-core new items: trpc, mongodb, graphql, kubernetes, আর দ্বিতীয় প্রস্তাবে tokens 2/3: nextjs, prisma, within budget. শিক্ষাটি সংখ্যায় নয়, তালিকায়: Kubernetes আর দ্বিতীয় একটি database একটি দোকানের MVP-তে কোনো মূল সুবিধা দেয় না, কিন্তু প্রতিটি নতুন ধরনের ব্যর্থতা আনে। GraphQL আর tRPC দুটোই API-র চুক্তির জন্য; একসাথে দুটি নতুন টুল একই সমস্যার জন্য একটি সতর্ক সংকেত। একটি token বাকি থাকল, যা পরে সত্যিকারের দরকারে খরচ করা যাবে। মডেলের দুর্বলতা: এটি সব নতুন জিনিসকে সমান ভারী ধরে, অথচ Kubernetes আর Prisma শেখা এক মাপের কাজ নয়।

৭ · ওজন দেওয়া সিদ্ধান্তের ছক — চারটি দৃশ্যপট

কঠিন শর্তের পর একাধিক প্রার্থী টিকে থাকলে decision matrix কাজে লাগে। পদ্ধতি সহজ: কয়েকটি মাপকাঠি বাছুন, প্রতিটিকে ওজন দিন যাতে যোগফল ১০০ হয়, প্রতিটি stack-কে প্রতিটি মাপকাঠিতে ১ থেকে ৫ স্কোর দিন, তারপর স্কোর × ওজন যোগ করে ১০০ দিয়ে ভাগ করুন। ফলাফল ১ থেকে ৫-এর মধ্যে একটি সংখ্যা।

মোট = Σ (স্কোরi × ওজনi) ÷ ১০০

আমরা ছয়টি মাপকাঠি নিয়েছি: দলের দক্ষতা (team), hosting-এর সাথে মিল (hosting), বাজারে আসার গতি (speed), real-time ক্ষমতা (realtime), SEO, আর দীর্ঘমেয়াদি রক্ষণাবেক্ষণ (maintain). প্রথমটি দৃশ্যপট অনুযায়ী বদলায়, কারণ দল বদলায়; বাকি পাঁচটির স্কোর stack-এর নিজের, সব দৃশ্যপটে এক। প্রতিটি স্কোর এই পর্বের লেখকের বিচারে ধরে নেওয়া, মাপা নয়; আপনার দল ভিন্ন স্কোর দিতে পারে, আর দেওয়াই উচিত। Hosting-এর স্কোর মানে কম খরচের hosting-এ চালানোর সহজতা।

StackhostingspeedrealtimeSEOmaintain
Laravel55354
Next.js + Prisma24354
MERN13523
Django25355
FastAPI + React13423

চারটি দৃশ্যপট, প্রতিটির নিজের দল আর ওজন:

  • A · shared hosting-এ ছোট দোকান: ২ অংশের দৃশ্যপট। দল: একজন Laravel ফ্রিল্যান্সার। ওজন: team ২৫, hosting ৩৫, speed ১৫, realtime ০, SEO ১৫, maintain ১০.
  • B · startup-এর MVP: দুজন TypeScript আর React জানা ডেভেলপার, তিন মাসে পণ্য, PaaS-এ চালানোর বাজেট আছে। ওজন: team ৩০, hosting ৫, speed ৩৫, realtime ৫, SEO ১৫, maintain ১০.
  • C · chat-সহ real-time marketplace: বিক্রেতা আর ক্রেতা live দরদাম করেন। দল JavaScript-এ সবচেয়ে অভ্যস্ত, VPS চালাতে পারে। ওজন: team ২৫, hosting ৫, speed ১৫, realtime ৩৫, SEO ৫, maintain ১৫.
  • D · Python-এর data দলের internal admin tool: তিনজন data analyst, Python আর pandas জানেন, অফিসের ভেতরে ব্যবহার হবে। ওজন: team ৩৫, hosting ৫, speed ৩০, realtime ০, SEO ০, maintain ৩০.

দলের স্কোর (team): A-তে Laravel ৫, Next.js ২, MERN ২, Django ১, FastAPI ১; B-তে ২, ৫, ৪, ২, ২; C-তে ৩, ৪, ৫, ২, ৩; D-তে ১, ২, ২, ৫, ৪. সব দৃশ্যপটের ফল একসাথে (একটি scratch script-এ হিসাব করা, নিচের runnable block-এর একই সূত্রে):

দৃশ্যপট১ম২য়৩য়ব্যবধান (১ম − ২য়)
A · ছোট দোকানLaravel 4.90Next.js 2.95, Django 2.95MERN 1.901.95
B · startup MVPNext.js 4.30Laravel 3.90Django 3.850.40
C · real-time marketplaceMERN 4.05Laravel 3.65Next.js 3.600.40
D · Python দলের admin toolDjango 4.85Laravel 3.30FastAPI 3.251.55

A-র ফলাফল আসলে ছক ছাড়াই জানা ছিল: hosting-এর কঠিন শর্তে Next.js SSR আর Django আগেই বাদ। D-ও পরিষ্কার: Python দল আর Django-র তৈরি admin (পর্ব ৬৮) একে অপরের জন্য তৈরি। আকর্ষণীয় হলো B আর C, যেখানে ব্যবধান মাত্র 0.40. এখানে প্রশ্ন ওঠে: বিজয়ী কতটা মজবুত? নিচের block C-র ছক চালায়, আর খোঁজে realtime থেকে SEO-তে কত পয়েন্ট ওজন সরালে প্রথম স্থান বদলায়। একে বলে sensitivity analysis.

// ওজন দেওয়া সিদ্ধান্তের ছক: real-time marketplace (চ্যাটসহ)। সব স্কোর ধরে নেওয়া, ১ থেকে ৫
const criteria = ['team', 'hosting', 'speed', 'realtime', 'seo', 'maintain'];
const weights  = [  25,      5,       15,       35,       5,       15   ]; // যোগফল 100
const scores = {
  'Laravel':      [3, 5, 5, 3, 5, 4],
  'Next+Prisma':  [4, 2, 4, 3, 5, 4],
  'MERN':         [5, 1, 3, 5, 2, 3],
  'Django':       [2, 2, 5, 3, 5, 5],
  'FastAPI+React':[3, 1, 3, 4, 2, 3],
};
function rank(w) {
  return Object.entries(scores)
    .map(([name, s]) => [name, s.reduce((sum, x, i) => sum + x * w[i], 0)])  // পূর্ণসংখ্যা, ভাগ পরে
    .sort((a, b) => b[1] - a[1]);
}
const table = rank(weights);
table.forEach(([name, total], i) => console.log(`${i + 1}. ${name.padEnd(14)} ${(total / 100).toFixed(2)}`));
// সংবেদনশীলতা: realtime থেকে কত ওজন seo-তে সরালে বিজয়ী বদলায়?
const winner = table[0][0];
for (let d = 1; d <= weights[3]; d++) {
  const w = [...weights]; w[3] -= d; w[4] += d;
  const r = rank(w);
  const old = r.find(([n]) => n === winner)[1];
  if (r[0][0] !== winner && r[0][1] > old) {          // সমান হলে বদল ধরা হয় না
    console.log(`move ${d} points realtime -> seo: winner ${winner} -> ${r[0][0]} (${(r[0][1] / 100).toFixed(2)} vs ${(old / 100).toFixed(2)})`);
    break;
  }
}

আউটপুট: 1. MERN 4.05, 2. Laravel 3.65, 3. Next+Prisma 3.60, 4. Django 3.40, 5. FastAPI+React 3.20; তারপর move 9 points realtime -> seo: winner MERN -> Laravel (3.83 vs 3.78). অর্থাৎ realtime-এর ওজন ৩৫ থেকে ২৬-এ নামালেই বিজয়ী বদলে যায়। কেন এত তাড়াতাড়ি? প্রতি এক পয়েন্ট সরালে MERN হারায় 0.03 (realtime-এ ৫, SEO-তে ২: ৫ − ২ = ৩, ÷ ১০০), আর Laravel পায় 0.02 (৫ − ৩ = ২). প্রতি পয়েন্টে ব্যবধান কমে 0.05, আর শুরুর ব্যবধান 0.40; তাই ৮ পয়েন্টে সমান (3.81 আর 3.81), ৯-এ উল্টো। পূর্ণসংখ্যায় হিসাব রাখা হয়েছে, যাতে দশমিকের ক্ষুদ্র ত্রুটি একটি সমান ফলকে ভুল করে “জয়” না বানায়।

ওজন আর মোট স্কোর
realtime / SEO
MERN
Laravel
Next+Prisma
ব্যবধান MERN − Laravel
  1. শুরু। realtime ৩৫, SEO ৫. MERN 4.05, Laravel 3.65, ব্যবধান 0.40. দেখে মনে হয় MERN পরিষ্কার বিজয়ী। কিন্তু ওজনগুলো একজনের অনুমান।
  2. ৫ পয়েন্ট সরানো। realtime ৩০, SEO ১০. MERN হারায় ৫ × 0.03 = 0.15, হয় 3.90; Laravel পায় ৫ × 0.02 = 0.10, হয় 3.75. ব্যবধান কমে 0.15-এ।
  3. ৮ পয়েন্ট। realtime ২৭, SEO ১৩. দুজনেই 3.81. সমান ফলকে কোনো জয় বলা যায় না; এই বিন্দুতে ছক আর কিছু বলছে না।
  4. ৯ পয়েন্ট। realtime ২৬, SEO ১৪. Laravel 3.83, MERN 3.78, Next.js-ও 3.78. মাত্র ৯ পয়েন্টে প্রথম স্থান বদলাল। সিদ্ধান্ত আসলে এই প্রশ্নে: বিক্রেতারা কি Google থেকে আসবেন, নাকি অ্যাপের ভেতরের live দরদামই পণ্যের প্রাণ? এই প্রশ্নের উত্তর খুঁজুন, ছকের দশমিক নয়।

ছকের সবচেয়ে বড় বিপদ মিথ্যা নির্ভুলতা। “4.05 বনাম 3.65” দেখতে বৈজ্ঞানিক লাগে, কিন্তু ভেতরের প্রতিটি সংখ্যা মতামত। তিনটি অভ্যাস একে সৎ রাখে: ওজন স্কোর দেওয়ার আগে লিখে ফেলা (নইলে মন পছন্দের stack জেতানোর মতো ওজন বসায়), দলের কয়েকজন আলাদাভাবে স্কোর দিয়ে তারপর মেলানো, আর প্রতিবার সংবেদনশীলতা দেখা। B দৃশ্যপটেও একই ঘটনা: team থেকে hosting-এ মাত্র ১০ পয়েন্ট সরালে Next.js-এর জায়গায় Laravel প্রথম হয় (4.20 বনাম 4.00).

৮ · Framework-এর স্বাস্থ্য পড়া — আজকের পাবলিক তথ্য থেকে

একটি framework পাঁচ বছর বাঁচবে কি না, তা কেউ নিশ্চিত বলতে পারে না, কিন্তু কয়েকটি সংকেত পাবলিকভাবে দেখা যায়। GitHub-এর star বা download-এর বড় সংখ্যা জনপ্রিয়তা দেখায়, স্বাস্থ্য নয়; আর আমরা কোনো download সংখ্যা এখানে দিচ্ছি না। কাজের সংকেতগুলো:

  • লিখিত support policy আর LTS: কোন version কতদিন security fix পাবে, তা কি তারিখসহ লেখা আছে?
  • Release cadence: নিয়মিত patch আসে কি না, আর major version কতদিন পরপর। খুব ধীর মানে মৃত নয়, খুব দ্রুত মানে ভালো নয়।
  • রক্ষণাবেক্ষণকারী: একজন মানুষের শখের প্রজেক্ট, নাকি একটি দল, foundation বা প্রতিষ্ঠান? একজন চলে গেলে প্রজেক্ট থামবে কি না, তাকে বলে bus factor.
  • Ecosystem: auth, payment, admin, test-এর library আছে কি না, আর সেগুলো নিজেরাও রক্ষণাবেক্ষণ পায় কি না।
  • Upgrade-এর পথ: major version-এ breaking change কতটা, upgrade guide আর codemod আছে কি না।

লেখার দিনে (৪ নভেম্বর ২০২৬) আমরা একটি ছোট Node script দিয়ে npm, PyPI, Packagist আর RubyGems-এর পাবলিক registry থেকে প্রতিটি package-এর stable release-গুলো গুনেছি। সত্যিকারের run, Node 24:

~/lab$ node health.mjs
npm @sveltejs/kit          3.1.1     2026-10-29  releases/12m= 56  majors=2,3
npm @trpc/server           11.24.0   2026-11-03  releases/12m= 27  majors=11,10
npm express                5.3.0     2026-10-09  releases/12m=  7  majors=4,5
npm next                   16.4.5    2026-11-03  releases/12m= 90  majors=16,15,14
npm nuxt                   4.6.4     2026-11-02  releases/12m= 31  majors=3,4
npm react                  19.3.1    2026-10-14  releases/12m= 29  majors=19
npm vue                    3.5.44    2026-10-13  releases/12m= 22  majors=3
packagist laravel/framework 13.40.0   2026-11-03  releases/12m=125  majors=12,11,10,13,9
pypi Django                6.1.3     2026-11-03  releases/12m= 34  majors=5,4,6
pypi fastapi               0.162.0   2026-10-23  releases/12m=119  majors=0
rubygems rails             8.1.4     2026-09-24  releases/12m=  5  majors=8,7

কলামগুলো: সর্বোচ্চ stable version, তার প্রকাশের তারিখ, গত ১২ মাসে কতটি stable release (pre-release বাদ), আর সেই release-গুলো কোন কোন major লাইনে। Next.js-এর ৯০টি release তিনটি লাইনে (১৬, ১৫, ১৪), অর্থাৎ পুরোনো লাইনেও fix যাচ্ছে। Laravel-এর ১২৫টি পাঁচটি লাইনে ছড়ানো; নথি অনুযায়ী minor আর patch প্রায় প্রতি সপ্তাহে আসতে পারে। Express-এর মাত্র ৭টি মানে মৃত নয়: পরিপক্ব, ছোট library-তে কম বদল প্রত্যাশিত। FastAPI এখনো 0.x: semver অনুযায়ী 0.x-এ minor version-এও ভাঙন আসতে পারে, তাই version ঠিকভাবে pin করা জরুরি (পর্ব ৫-এর lockfile). Rails-এর ৫টি কম দেখালেও Rails সাধারণত কম কিন্তু বড় release দেয়। প্রতিটি সংখ্যা প্রকল্পের নিজের নীতির সাথে মিলিয়ে পড়ুন।

একই দিনে তিনটি framework-এর লিখিত নীতি তাদের অফিসিয়াল পাতা থেকে পড়া হয়েছে (তারিখগুলো লেখার সময়ের; বদলাতে পারে, তাই নিজে আবার দেখুন):

Frameworkনীতি, তাদের পাতা অনুযায়ীলেখার সময়ের অবস্থা
Next.jsনতুন major আসা পর্যন্ত Active LTS; তারপর Maintenance LTS, প্রথম প্রকাশ থেকে দুই বছর, শুধু জরুরি bug আর security fix16.x Active (প্রকাশ অক্টোবর ২০২৫); 15.x Maintenance, security fix ৩১ জানুয়ারি ২০২৭ পর্যন্ত বাড়ানো
Laravelপ্রতি বছর একটি major (মোটামুটি বছরের প্রথম ভাগে); প্রতিটিতে bug fix ১৮ মাস, security fix ২ বছর13 সর্বশেষ (২০২৬-এর প্রথম ভাগ); 12-এর security fix ফেব্রুয়ারি ২০২৭ পর্যন্ত
Djangoনির্দিষ্ট LTS release প্রায় তিন বছর সমর্থন পায়; পাতায় ঘোষণা, ২০২৮ থেকে version-এর নাম বছর দিয়ে আর প্রতিটি feature release-ই তিন বছর5.2 LTS, বাড়তি সমর্থন এপ্রিল ২০২৮ পর্যন্ত; 6.1 সর্বশেষ; পরের LTS 6.2, এপ্রিল ২০২৭-এ প্রত্যাশিত

পাঁচ বছরের অ্যাপে আপনি অন্তত দুই-তিনবার major upgrade করবেন, framework যেটাই হোক। তাই প্রশ্ন হলো কোনটির upgrade-এর পথ লিখিত আর পূর্বানুমেয়। প্রতিটি LTS-এর শেষ তারিখ ক্যালেন্ডারে লিখে রাখুন; মেয়াদ পার হওয়া framework-এর version-কে বলে end of life, যার পর নতুন security fix আসে না।

খালি ফোল্ডার থেকে “hello products” — একটি local run

শুরু করার গতিও একটি সংকেত, যদিও ছোট। দুটি stack-এ খালি ফোল্ডার থেকে একটি /products পাতা, যা তিনটি পণ্যের তালিকা দেখায়, চালু হওয়া পর্যন্ত সময় মাপা হয়েছে। সত্যিকারের run, একটি Windows যন্ত্রে একবার; ফোল্ডারের পথ বদলে ~/lab লেখা হয়েছে।

~/lab/nx$ npx create-next-app@16.4.5 bazarghar --ts --app --no-tailwind --no-eslint \
           --no-src-dir --no-react-compiler --import-alias "@/*" --use-npm --skip-install --yes
~/lab/nx/bazarghar$ npm install --no-audit --no-fund
~/lab/nx/bazarghar$ # app/products/page.tsx: তিনটি পণ্যের <ul>
~/lab/nx/bazarghar$ npx next dev -p 47851 -H 127.0.0.1
▲ Next.js 16.4.5 (Turbopack)
- Local:         http://127.0.0.1:47851
✓ Ready in 317ms
 GET /products 200 in 226ms (next.js: 130ms, application-code: 96ms)
scaffold+install: 33.9 s
first /products response after dev start: 2.8 s
total: 36.8 s
next 16.4.5 react 19.3.0      node_modules: 378M

~/lab/dj$ python -m venv .venv && .venv/Scripts/python -m pip install -q "Django==6.1.3"
~/lab/dj$ .venv/Scripts/django-admin startproject bazarghar .
~/lab/dj$ # bazarghar/products.py আর urls.py-তে একটি path
~/lab/dj$ .venv/Scripts/python manage.py runserver 127.0.0.1:47852 --noreload
~/lab/dj$ curl -s http://127.0.0.1:47852/products/
<ul><li>Chal 5kg - 450 taka</li><li>Dal 1kg - 140 taka</li><li>Tel 1L - 190 taka</li></ul>
venv+install+startproject: 15.0 s
first /products/ response after runserver: 0.6 s
total: 15.8 s
django 6.1.3 python 3.14.4    .venv: 56M

সত্যিকারের run, একবার মাপা; এটি কোনো benchmark নয়। Next.js-এ মোট ৩৬.৮ সেকেন্ড, যার বেশিরভাগ package নামানো, আর node_modules 378 MB; Django-তে ১৫.৮ সেকেন্ড আর venv 56 MB. পার্থক্যের বড় অংশ network আর যন্ত্রের cache-এর ওপর নির্ভর করে: এই যন্ত্রে আগে থেকে npm আর pip-এর cache ভরা থাকতে পারে, আর অন্য যন্ত্রে সংখ্যা অনেক আলাদা হবে। Laravel-ও মাপার পরিকল্পনা ছিল, কিন্তু এই run-এ portable PHP নামানো সম্ভব হয়নি, তাই Laravel-এর কোনো সংখ্যা নেই। সবচেয়ে বড় শিক্ষা: দুটোই এক মিনিটের কম। শুরুর এই সেকেন্ডগুলো সিদ্ধান্তে প্রায় গুরুত্বহীন; গুরুত্বপূর্ণ হলো পরের ছয় মাস দল কত দ্রুত নিরাপদ feature যোগ করতে পারে।

৯ · ভুল বাছাইয়ের দাম, দরজা খোলা রাখা আর ADR

সতর্ক থাকলেও কখনো কখনো stack ভুল প্রমাণ হয়: দল বদলায়, পণ্য বদলায়, বা framework থেমে যায়। তখন সরে যাওয়ার খরচ কতটা, তা মূলত তিনটি জিনিসের ওপর নির্ভর করে, যা আজই নিয়ন্ত্রণ করা যায়।

  • পরিষ্কার API boundary: UI আর ব্যবসার logic যদি একটি লিখিত API (REST, পর্ব ৩৫-এর OpenAPI) দিয়ে আলাদা থাকে, তবে একদিকে বদলালে অন্যদিক টেকে। পাতার ভেতরে SQL আর logic মেশানো থাকলে সব একসাথে নতুন করে লিখতে হয়।
  • Standard database: PostgreSQL বা MySQL-এর সাধারণ টেবিল যেকোনো ভাষা আর framework পড়তে পারে। একটি platform-এর নিজস্ব database বা নিজস্ব query ভাষায় বাঁধা থাকলে ডেটা সরানো আলাদা একটি প্রকল্প হয়ে যায়।
  • Test আর lock-in কম রাখা: আগের আচরণ test-এ লেখা থাকলে নতুন stack-এ তা মিলিয়ে দেখা যায় (পর্ব ৭৫)। Platform-এর নিজস্ব queue, KV store বা cron-এর ওপর অনেক কোড থাকলে একটি পাতলা নিজের interface-এর পেছনে রাখুন।

নিচের মডেলে বাজারঘরের ছয়টি module নতুন stack-এ লেখার খরচ, চারটি পরিস্থিতিতে। সব সংখ্যা ধরে নেওয়া উদাহরণ: module-প্রতি দিন, জটের গুণক, ডেটা সরানোর দিন, আর আচরণ যাচাইয়ের বাড়তি অংশ।

// ভুল stack থেকে সরার খরচ: সব সংখ্যা ধরে নেওয়া উদাহরণ, মাপা নয়
const modules = { catalog: 8, cart: 6, checkout: 10, orders: 7, admin: 12, auth: 5 }; // নতুন stack-এ লেখার দিন
const DEVS = 2, DAYS_PER_WEEK = 5;
function estimate({ boundary, database, testsExist }) {
  const base = Object.values(modules).reduce((a, b) => a + b, 0);
  const tangle = boundary === 'clean' ? 1.0 : 1.6;   // UI আর logic জট পাকানো থাকলে বাড়তি
  const data = database === 'same' ? 3 : 15;          // ডেটা সরানো, যাচাই, rollback-এর মহড়া
  const verify = testsExist ? 0.10 : 0.35;            // আগের আচরণ মিলিয়ে দেখার খরচ
  const days = Math.round((base * tangle + data) * (1 + verify));
  return { days, weeks: (days / DEVS / DAYS_PER_WEEK).toFixed(1) };
}
const cases = [
  ['clean API, same DB, tests', { boundary: 'clean', database: 'same', testsExist: true }],
  ['clean API, new DB, tests',  { boundary: 'clean', database: 'move', testsExist: true }],
  ['tangled, same DB, no tests', { boundary: 'tangled', database: 'same', testsExist: false }],
  ['tangled, new DB, no tests',  { boundary: 'tangled', database: 'move', testsExist: false }],
];
for (const [label, c] of cases) {
  const e = estimate(c);
  console.log(`${label.padEnd(27)} ${String(e.days).padStart(3)} dev-days  ~${e.weeks} weeks for ${DEVS} devs`);
}

আউটপুট: clean API, same DB, tests → 56 dev-days ~5.6 weeks; clean API, new DB, tests → 69, প্রায় ৬.৯ সপ্তাহ; tangled, same DB, no tests → 108, প্রায় ১০.৮ সপ্তাহ; tangled, new DB, no tests → 124, প্রায় ১২.৪ সপ্তাহ। প্রথম সারির হিসাব হাতে: module-গুলোর যোগফল ৪৮ দিন; জট নেই তাই × 1.0; ডেটা একই তাই + ৩ = ৫১; test আছে তাই × 1.10 = 56.1, গোল করে ৫৬. শেষ সারিতে ৪৮ × 1.6 = 76.8, + ১৫ = 91.8, × 1.35 = 123.93, অর্থাৎ ১২৪. একই দোকান, একই দল, শুধু আগের তিনটি অভ্যাসের পার্থক্যে খরচ দ্বিগুণের বেশি। আর এখানে বাদ আছে সবচেয়ে বড় খরচ: সেই সময়ে নতুন feature বন্ধ থাকা।

সরে যাওয়ার পথও গুরুত্বপূর্ণ। পুরোটা একবারে নতুন করে লেখার বদলে Martin Fowler-এর ২০০৪ সালের লেখায় বর্ণিত strangler fig কৌশল: নতুন অংশগুলো পুরোনোর পাশে একটি একটি করে বসানো, সামনে একটি proxy বা router দিয়ে অনুরোধ নতুন দিকে ঘোরানো, যতক্ষণ না পুরোনোটি খালি হয়। বিস্তারিত Software Engineering কোর্সের technical debt আর legacy code পর্বে।

এক পাতার সিদ্ধান্তের দলিল: ADR

Michael Nygard ২০১১ সালে একটি ব্লগ লেখায় Architecture Decision Record বা ADR-এর একটি সহজ রূপ প্রস্তাব করেন: প্রতিটি গুরুত্বপূর্ণ সিদ্ধান্তের জন্য repository-তে একটি ছোট ফাইল, যাতে থাকে শিরোনাম, অবস্থা, প্রেক্ষাপট, সিদ্ধান্ত আর পরিণাম। ছয় মাস পরে “MongoDB কেন নয়?” প্রশ্নের উত্তর লেখা থাকে। পুরোনো ADR মুছে বা বদলে দেওয়া হয় না; নতুন সিদ্ধান্তে নতুন ADR লিখে পুরোনোটিকে “বাতিল, ADR-00X দিয়ে প্রতিস্থাপিত” চিহ্ন দেওয়া হয়। ADR-এর তত্ত্ব Software architecture পর্বে। নিচের stepper-এ দৃশ্যপট B-র ADR তৈরি হতে দেখুন।

docs/adr/0001-stack.mdশিরোনাম আর প্রেক্ষাপট
# ADR-0001: বাজারঘর MVP-র stack
অবস্থা: প্রস্তাবিত · ২০২৬-১১-০৪
## প্রেক্ষাপট
দুজন ডেভেলপার, দুজনেই TypeScript আর React-এ
production চালিয়েছেন। ৩ মাসে প্রথম সংস্করণ।
ক্যাটালগের পাতা Google-এ আসা জরুরি।
PaaS-এ চালানোর মাসিক বাজেট আছে।
বিকল্পযা বিবেচনা করা হলো
## বিবেচিত বিকল্প
১. Next.js + Prisma + PostgreSQL
২. Laravel + Inertia (React) + PostgreSQL
৩. Django + React + PostgreSQL
৪. Vite SPA + Express + MongoDB
ছাঁকনিকঠিন শর্ত
## কঠিন শর্ত
SEO জরুরি → শুধু SPA (৪) দুর্বল, বাদ
PaaS-এ Node, PHP, Python সব চলে → বাকি সবাই টেকে
টিকে আছে: ১, ২, ৩
ছকওজন আগে লেখা, স্কোর ধরে নেওয়া
ওজন: team 30 · hosting 5 · speed 35
      realtime 5 · seo 15 · maintain 10
Next.js 4.30 · Laravel 3.90 · Django 3.85
সংবেদনশীলতা: team→hosting ১০ পয়েন্টে
Laravel 4.20, Next.js 4.00
সিদ্ধান্ত আর পরিণামঅবস্থা: গৃহীত
## সিদ্ধান্ত
Next.js 16 (App Router) + Prisma 7 + PostgreSQL,
একটি modular monolith.
## পরিণাম
+ দলের পরিচিত ভাষা, এক type দুই দিকে
− shared hosting-এ চলবে না; PaaS বা VPS লাগবে
− version বদলের সাথে Next.js-এর API বদলায়
## আবার ভাবব যদি
দল PHP-ভিত্তিক হয়, বা hosting shared-এ নামাতে হয়
  1. প্রেক্ষাপট আগে। ADR শুরু হয় পরিস্থিতি দিয়ে, framework-এর নাম দিয়ে নয়। দল, সময়, SEO আর বাজেট, ঠিক ২ অংশের প্রশ্নগুলোর উত্তর। অবস্থা এখনো “প্রস্তাবিত”।
  2. বিকল্পের তালিকা। চারটি বাস্তব বিকল্প লেখা হলো, যার মধ্যে অন্তত একটি দলের অভ্যাসের বাইরে (Django). শুধু পছন্দেরটি লিখলে ADR ঘোষণাপত্র হয়ে যায়।
  3. কঠিন শর্ত। SEO জরুরি, তাই শুধু browser-এ render হওয়া SPA (বিকল্প ৪) বাদ। PaaS-এ সব runtime চলে, তাই hosting এখানে কাউকে বাদ দেয় না। তিনটি টিকে থাকে।
  4. ছক আর সংবেদনশীলতা। ৭ অংশের সংখ্যা: Next.js 4.30, Laravel 3.90, Django 3.85. ADR-এ সংবেদনশীলতাও লেখা হলো: team থেকে hosting-এ ১০ পয়েন্ট সরালে Laravel জেতে। এর মানে, hosting সস্তা করার চাপ এলে সিদ্ধান্তটি আবার ভাবতে হবে।
  5. সিদ্ধান্ত, পরিণাম আর ফেরার শর্ত। অবস্থা “গৃহীত”। পরিণামে ভালো আর খারাপ দুই দিকই লেখা, আর শেষে “আবার ভাবব যদি”: কোন ঘটনা ঘটলে এই সিদ্ধান্ত নতুন ADR দিয়ে প্রতিস্থাপিত হবে। এই অংশটিই ADR-কে জীবন্ত রাখে।

পুরো ADR একসাথে, যা আপনি নিজের repository-র docs/adr/ ফোল্ডারে রাখতে পারেন। কাঠামোটি Nygard-এর রূপের সাথে “বিবেচিত বিকল্প” আর “আবার ভাবব যদি” যোগ করা; অনেক দল এমন ছোট সংযোজন করে।

# ADR-0001: বাজারঘর MVP-র stack

অবস্থা: গৃহীত · ২০২৬-১১-০৪ · সিদ্ধান্তদাতা: দুই ডেভেলপার + পণ্যের মালিক

## প্রেক্ষাপট
- দল: দুজন, TypeScript আর React-এ production-এর অভিজ্ঞতা; Python বা PHP-তে নয়
- পণ্য: ক্যাটালগ, cart, checkout, অর্ডারের ইতিহাস; real-time নেই
- SEO: ক্যাটালগের পাতা search-এ আসা জরুরি
- সময়: ৩ মাসে প্রথম সংস্করণ
- Hosting: একটি PaaS-এ web + managed PostgreSQL, মাসিক বাজেট আছে

## বিবেচিত বিকল্প
1. Next.js 16 + Prisma 7 + PostgreSQL
2. Laravel 13 + Inertia (React) + PostgreSQL
3. Django 6 + React + PostgreSQL
4. Vite SPA + Express + MongoDB  (SEO-র শর্তে বাদ)

## মূল্যায়ন
ওজন (স্কোরের আগে লেখা): team 30, hosting 5, speed 35, realtime 5, seo 15, maintain 10
ফল (স্কোর ধরে নেওয়া, ১–৫): Next.js 4.30, Laravel 3.90, Django 3.85
সংবেদনশীলতা: team থেকে hosting-এ ১০ পয়েন্ট সরালে Laravel 4.20 বনাম Next.js 4.00

## সিদ্ধান্ত
Next.js 16 (App Router) + Prisma 7 + PostgreSQL, একটি modular monolith
(catalog, cart, orders, auth আলাদা module). Innovation token: Next.js আর Prisma (২/৩)।

## পরিণাম
+ দলের পরিচিত ভাষা; Zod schema আর type client ও server-এ ভাগ
+ SSR/SSG দিয়ে SEO; PostgreSQL standard, তাই পরে অন্য backend পড়তে পারবে
− shared hosting-এ চলবে না
− Next.js-এর major version-এ API বদলায়; বছরে একবার upgrade-এর সময় রাখতে হবে
− admin panel নিজে বানাতে হবে (Django বা Laravel-এ যা প্রায় তৈরি)

## আবার ভাবব যদি
- দলের বেশিরভাগ PHP বা Python-ভিত্তিক হয়ে যায়
- hosting shared-এ নামাতে হয়
- live chat বা দরদাম পণ্যের মূল feature হয়ে ওঠে

আরও গভীরে: ওজন দেওয়া ছকটি multi-criteria decision analysis-এর সবচেয়ে সরল রূপ, যাকে weighted sum model বলা হয়; এর পরিচিত দুর্বলতা হলো এটি ধরে নেয় মাপকাঠিগুলো একে অপরের থেকে স্বাধীন আর একটির ঘাটতি অন্যটি দিয়ে পূরণ করা যায়। AHP-র মতো পদ্ধতি জোড়ায় জোড়ায় তুলনা করে ওজন বের করে আর মতামতের অসংগতি মাপে। বেশিরভাগ দলের জন্য সরল ছক আর সংবেদনশীলতাই যথেষ্ট।

পরীক্ষা ও ইন্টারভিউতে:

  • “কোন stack সেরা?” প্রশ্নের ভালো উত্তর? পাল্টা প্রশ্ন: দল, পণ্য, SEO, hosting, সময় আর রক্ষণাবেক্ষণ কী? তারপর trade-off সহ একটি সুপারিশ।
  • Modular monolith কী? একটি deploy, কিন্তু ভেতরে module-এর শক্ত সীমানা; module-গুলো শুধু ঘোষিত interface দিয়ে কথা বলে।
  • ADR-এ কী থাকে? শিরোনাম, অবস্থা, প্রেক্ষাপট, সিদ্ধান্ত, পরিণাম; পুরোনো ADR বদলানো হয় না, নতুন ADR দিয়ে প্রতিস্থাপিত হয়।
  • Innovation token কী বোঝায়? একটি দল অল্প কয়েকটি নতুন প্রযুক্তিই সামলাতে পারে; সেগুলো খরচ করুন যেখানে নতুনত্ব পণ্যের মূল সুবিধা দেয়।
  • Weights 40/30/30, A-র স্কোর 5/2/4, B-র 3/5/4: কে জেতে? A = 3.80, B = 3.90; B, কিন্তু ব্যবধান মাত্র 0.10, তাই সংবেদনশীলতা দেখা জরুরি।

১০ · AI-এর যুগে stack বাছাই

“আমার অনলাইন দোকানের জন্য সেরা stack কোনটি?” লিখলে AI সাধারণত আত্মবিশ্বাসের সাথে একটি নাম দেয়, সাথে চকচকে কিছু কারণ। সমস্যা হলো, AI আপনার দল, hosting বা বাজেট জানে না, যদি না আপনি বলেন; আর জনপ্রিয় লেখায় যা বেশি এসেছে, সেটিই তার উত্তরে বেশি আসে। এই বিষয়ে AI-এর সাধারণ ভুলগুলো:

AI যা প্রায়ই করেফলকীভাবে ধরবেন
প্রেক্ষাপট ছাড়াই একটি “সেরা” stack ঘোষণাআপনার কঠিন শর্ত (যেমন PHP-only hosting) উপেক্ষিতআগে নিজের সাত প্রশ্নের উত্তর দিয়ে তবে জিজ্ঞেস করুন
Download, star বা benchmark-এর সংখ্যা বানিয়ে বলামিথ্যা তথ্যে সিদ্ধান্তregistry, অফিসিয়াল support পাতা নিজে খুলে দেখুন
পুরোনো পরামর্শ: Create React App, Next.js-এর Pages Router-কে নতুন প্রজেক্টের ডিফল্ট বলাশুরুতেই বাতিল বা পুরোনো পথেঅফিসিয়াল “getting started” পাতা; React-এর দল ২০২৫ সালে CRA-কে নতুন অ্যাপের জন্য বাতিল ঘোষণা করেছে
MVP-তে Kubernetes, microservices, দুটি database, GraphQL একসাথেtoken-এর বাজেট ফুরিয়ে যায়, পণ্য দেরিতেinnovation token-এর হিসাব; প্রতিটি অংশের জন্য “কোন মাপা সমস্যা এটি মেটায়?”
অস্তিত্বহীন package বা “starter kit”-এর নামinstall ব্যর্থ, বা আরও খারাপ, একই নামের ক্ষতিকর packagenpm view বা registry-তে খোঁজা; রক্ষণাবেক্ষণকারী আর সাম্প্রতিক release দেখা
স্কোর দিয়ে ছক বানিয়ে ওজনগুলো চুপচাপ পছন্দের দিকে হেলানোনিরপেক্ষ দেখতে, আসলে আগেই ঠিক করা উত্তরওজন নিজে আগে লিখুন; AI-কে শুধু স্কোরের যুক্তি আর সংবেদনশীলতা জিজ্ঞেস করুন

AI-কে বিচারক নয়, বিপক্ষের উকিল বানান। আপনার নিজের প্রেক্ষাপট, কঠিন শর্ত আর ওজন দিয়ে তাকে দুর্বলতা খুঁজতে বলুন:

আমি একটি অনলাইন দোকানের stack বাছাই করছি। প্রেক্ষাপট: দুজন ডেভেলপার, TypeScript আর React জানেন; ৩ মাসে প্রথম সংস্করণ; ক্যাটালগের SEO জরুরি; PaaS-এ চালাব; real-time নেই। আমার ওজন (আগেই ঠিক করা, বদলাবে না): team 30, hosting 5, speed 35, realtime 5, seo 15, maintain 10. আমার প্রস্তাব: Next.js + Prisma + PostgreSQL. ১. এই প্রস্তাবের বিপক্ষে সবচেয়ে শক্ত তিনটি যুক্তি দাও, আর প্রতিটির জন্য বলো কোন বিকল্প সেখানে ভালো। ২. কোনো version, support-এর তারিখ বা সংখ্যা বললে উৎসের নাম দাও; নিশ্চিত না হলে "নিশ্চিত নই" লেখো। কোনো download সংখ্যা বানিয়ে বলবে না। ৩. কোন ঘটনা ঘটলে এই সিদ্ধান্ত আবার ভাবা উচিত, তার তালিকা দাও।

AI-এর stack-পরামর্শ হাতে পেলে

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন, তারপর “→ উত্তর” চাপুন।

প্র ০১“Choose boring technology” কি নতুনত্বের বিরোধী? তাহলে নতুন framework-গুলো জনপ্রিয় হয় কীভাবে?

Dan McKinley-র ২০১৫ সালের দিকের প্রবন্ধটি প্রায়ই ভুলভাবে উদ্ধৃত হয়, যেন তিনি বলছেন “নতুন কিছু কখনো ব্যবহার করবেন না”। আসলে তাঁর কথা প্রায় উল্টো: নতুনত্ব মূল্যবান, তাই তা সীমিত সম্পদ, আর সীমিত সম্পদ হিসাব করে খরচ করতে হয়। তিনি প্রতিষ্ঠানের হাতে মোটামুটি তিনটি innovation token কল্পনা করেন, আর নিজেই বলেন সংখ্যাটি কাল্পনিক। Token খরচ করার জায়গা হলো যেখানে নতুন প্রযুক্তি পণ্যের মূল সুবিধা দেয়; বাকি সব জায়গায় পরিচিত, একঘেয়ে প্রযুক্তি।

যুক্তির ভিত্তি হলো ব্যর্থতার জ্ঞান। একটি পুরোনো database বা framework-এর অজানা সমস্যা কম, কারণ হাজারো দল বছরের পর বছর ধরে সেগুলো খুঁজে পেয়েছে, নথিতে লিখেছে, আর monitoring-এর অভ্যাস গড়ে উঠেছে। নতুন প্রযুক্তিতে প্রতিটি অদ্ভুত আচরণ আপনাকে প্রথমবার বুঝতে হয়, প্রায়ই production-এ। তার ওপর প্রতিটি নতুন অংশের deploy, backup আর upgrade-এর খরচ যোগ হয়।

তাহলে নতুন framework জনপ্রিয় হয় কীভাবে? এমন দলের মাধ্যমে, যাদের জন্য সেই নতুনত্বই মূল সুবিধা, অথবা যারা token-এর দাম জেনে খরচ করতে রাজি। Next.js-এর শুরুর দিকের ব্যবহারকারীদের কাছে React-এ SSR সহজ হওয়াটাই ছিল মূল কারণ। সময়ের সাথে প্রযুক্তি একঘেয়ে হয়ে ওঠে: যা ২০১৬ সালে নতুন ছিল, তা আজ অনেক দলের কাছে পরিচিত, আর তখন সেটি আর token খরচ করে না। খেয়াল করুন, “একঘেয়ে” আপেক্ষিক: যে দল বছরের পর বছর Django চালিয়েছে, তার কাছে Django একঘেয়ে আর Next.js নতুন, আর আরেকটি দলের কাছে উল্টো।

মূল উপলব্ধি: প্রশ্নটি “নতুন বনাম পুরোনো” নয়, “কোথায় নতুনত্বের দাম দেওয়া সার্থক”। Token গুনে রাখলে উত্তেজনা আর দায়িত্বের মধ্যে ভারসাম্য রাখা সহজ হয়।

প্র ০২শুরু থেকেই microservices নিলে কী সমস্যা? আর monolith কখন সত্যিই ভাঙা উচিত?

Martin Fowler ২০১৫ সালের “MonolithFirst” লেখায় একটি পর্যবেক্ষণ দেন: তাঁর জানা সফল microservice-এর গল্পগুলোর প্রায় সবই শুরু হয়েছিল একটি monolith থেকে, যা বড় হয়ে ভাঙা হয়; আর শুরু থেকে microservice নিয়ে বানানো প্রকল্পের অনেকে বড় সমস্যায় পড়েছে। একই সময়ে অন্যরা পাল্টা যুক্তিও দিয়েছেন, যে monolith থেকে ভাঙা নিজেই কঠিন, তাই কিছু ক্ষেত্রে শুরু থেকেই আলাদা করা ভালো। বিতর্কটি আজও চলে।

শুরু থেকে microservices-এর মূল সমস্যা হলো সীমানা না জেনে সীমানা টানা। নতুন পণ্যে আপনি এখনো জানেন না কোন অংশগুলো একসাথে বদলায়। ভুল জায়গায় ভাগ করলে একটি feature-এর জন্য তিনটি সেবা, তিনটি deploy আর তাদের মধ্যের API-র চুক্তি একসাথে বদলাতে হয়। তার ওপর আসে বিতরণ ব্যবস্থার পুরো খরচ: network-এর ব্যর্থতা, timeout, distributed transaction, আলাদা log জোড়া লাগানো, আর অনেক deploy-এর pipeline. দুজনের একটি দলের জন্য এই খরচ প্রায়ই পণ্যের কাজের চেয়ে বড় হয়ে দাঁড়ায়।

Modular monolith এই দুইয়ের মাঝখানে। একটি deploy, একটি database, কিন্তু ভেতরে module-এর সীমানা শক্তভাবে রাখা: অন্য module-এর টেবিলে সরাসরি হাত না দেওয়া, শুধু ঘোষিত function দিয়ে কথা বলা। পরে সত্যিই কোনো module আলাদা করতে হলে সীমানা আগে থেকে টানা থাকে।

ভাঙার সঠিক সময় আসে মাপা কারণ থেকে। একটি অংশের চাপ ভিন্ন ধরনের, যেমন বাজারঘরের chat-এ হাজার খোলা সংযোগ, যা অর্ডারের CRUD-এর চেয়ে সম্পূর্ণ আলাদাভাবে scale হয়। অথবা দুটি দল একই কোডে একে অপরের deploy আটকাচ্ছে। অথবা একটি অংশের নিরাপত্তা বা নিয়মের প্রয়োজন আলাদা, যেমন payment. “বড় কোম্পানিরা করে” কোনো কারণ নয়; তাদের সমস্যা আর দল আপনার নয়।

মূল উপলব্ধি: সেবা ভাগ করা একটি সংগঠনের আর চাপের সমস্যার সমাধান, কোডের সৌন্দর্যের নয়। Monolith দিয়ে শুরু করে ভেতরে দেয়াল রাখুন, আর ভাঙুন যখন একটি মাপা সমস্যা তা দাবি করে।

প্র ০৩ওজন দেওয়া ছক যদি এত সহজে বদলায়, তবে এটি ব্যবহার করব কেন? সৎভাবে ব্যবহারের নিয়ম কী?

ছকের মূল্য উত্তর দেওয়ায় নয়, আলোচনাকে প্রকাশ্য করায়। ছক ছাড়া দুজন মানুষ “Next.js ভালো” আর “Laravel ভালো” বলে তর্ক করেন, আর কেউ বোঝেন না অন্যজন কোন জিনিসকে গুরুত্ব দিচ্ছেন। ছকে বসালে দেখা যায়, একজন SEO-কে ২০ ধরছেন, অন্যজন ৫. তর্কটি তখন framework থেকে সরে আসল প্রশ্নে যায়: আমাদের ব্যবসায় SEO কতটা গুরুত্বপূর্ণ?

এই পর্বের C দৃশ্যপটে মাত্র ৯ পয়েন্ট ওজন সরালে বিজয়ী বদলেছে। এটি ছকের দুর্বলতা নয়, বরং সবচেয়ে মূল্যবান তথ্য: দুটি বিকল্প প্রায় সমান, আর সিদ্ধান্ত নির্ভর করে একটি নির্দিষ্ট অনুমানের ওপর। সেই অনুমান যাচাই করতে সময় খরচ করা যুক্তিসংগত, যেমন বিক্রেতাদের সাথে কথা বলে জানা real-time দরদাম সত্যিই কতটা চান। অন্যদিকে A বা D-র মতো বড় ব্যবধানে ওজন অনেক বদলালেও ফল একই থাকে, তাই সেখানে বেশি ভাবনা অপচয়।

সৎ ব্যবহারের কয়েকটি নিয়ম অনুশীলনে কাজে লাগে। প্রথম, ওজন আগে, স্কোর পরে, আর ওজন লিখিত। দ্বিতীয়, স্কোর কয়েকজন আলাদাভাবে দেবেন, তারপর বড় অমিলগুলো নিয়ে আলোচনা; অমিলই দেখায় কোথায় তথ্যের ঘাটতি। তৃতীয়, প্রতিটি স্কোরের পাশে এক লাইনের কারণ। চতুর্থ, সংবেদনশীলতা দেখা, আর ADR-এ লেখা কোন ওজন বদলালে সিদ্ধান্ত উল্টাবে। পঞ্চম, কঠিন শর্তকে কখনো ওজন হিসেবে না রাখা।

মূল উপলব্ধি: ছক একটি আয়না, ভবিষ্যদ্বাণী নয়। এটি দেখায় আপনি কী মূল্য দিচ্ছেন আর সিদ্ধান্তটি কোন অনুমানের ওপর দাঁড়িয়ে; সেই অনুমানগুলো যাচাই করাই আসল কাজ।

প্র ০৪ভুল stack বুঝতে পারলে কি পুরোটা নতুন করে লেখা উচিত? ইতিহাস কী শেখায়?

সবচেয়ে বেশি উদ্ধৃত সতর্কবার্তাগুলোর একটি Joel Spolsky-র ২০০০ সালের লেখা “Things You Should Never Do”. সেখানে তিনি Netscape-এর browser নতুন করে লেখার সিদ্ধান্তকে উদাহরণ হিসেবে দেখান: তাঁর বর্ণনায়, নতুন সংস্করণ আসতে কয়েক বছর লেগেছিল, আর সেই সময়ে বাজার প্রতিদ্বন্দ্বীর হাতে চলে যায়। তাঁর মূল যুক্তি ছিল, পুরোনো কোডে বছরের পর বছর ধরে জমা হওয়া bug-এর সমাধান আর ছোট ছোট শিক্ষা থাকে, যা নতুন করে লিখলে হারিয়ে যায়, আর পুরোনো কোড পড়তে কঠিন লাগা মানেই সেটি খারাপ নয়।

এর বিকল্প হিসেবে Martin Fowler ২০০৪ সালে strangler fig-এর ধারণা বর্ণনা করেন, অস্ট্রেলিয়ার এক ধরনের লতাগাছের নামে, যা একটি গাছকে ঘিরে বড় হয়ে একসময় তার জায়গা নেয়। সফটওয়্যারে এর মানে: পুরোনো অ্যাপের সামনে একটি router বা proxy রাখা, নতুন stack-এ একটি একটি অংশ বানানো, আর সেই অংশের অনুরোধ নতুন দিকে ঘোরানো। প্রতিটি ধাপ ছোট, ফেরানো যায়, আর পণ্য কখনো থেমে থাকে না।

বাজারঘরের ক্ষেত্রে ধরুন Express আর একটি জট পাকানো SPA থেকে Next.js-এ যেতে চান। প্রথমে ক্যাটালগের পাতা, যেখানে SEO-র লাভ সবচেয়ে বেশি, Next.js-এ বানিয়ে proxy দিয়ে /products সেখানে পাঠান, আর পুরোনো API থেকেই ডেটা নিন। Database একই থাকে, তাই ডেটা সরানোর প্রয়োজন নেই। তারপর cart, তারপর checkout. এই পর্বের খরচের মডেলেও দেখা গেছে, পরিষ্কার API আর একই database থাকলে খরচ অর্ধেকের কম।

তবে নতুন করে লেখা কখনো কখনো যুক্তিসংগত, যেমন অ্যাপ খুব ছোট, বা framework-এর সমর্থন শেষ হয়ে নিরাপত্তার ঝুঁকি তৈরি হয়েছে। একটি উপকারী পরীক্ষা: পুরোনো অ্যাপের সব আচরণ কি test-এ লেখা যায়? না গেলে নতুন অ্যাপ সেই আচরণ ভুলে যাবে।

মূল উপলব্ধি: ভুল stack থেকে সরে আসা প্রায় সবসময় সম্ভব, কিন্তু তার দাম আজকের অভ্যাস ঠিক করে: পরিষ্কার boundary, standard database আর test. বড় এক লাফের চেয়ে অনেক ছোট পদক্ষেপ নিরাপদ।

প্র ০৫একটি framework “মরে যাচ্ছে” কি না, কীভাবে বুঝবেন? জনপ্রিয় framework-ও কি থেমে যায়?

জনপ্রিয়তা আর স্থায়িত্ব এক জিনিস নয়, আর ইতিহাসে এর পরিষ্কার উদাহরণ আছে। AngularJS, অর্থাৎ Angular-এর প্রথম প্রজন্ম, এক সময় খুব জনপ্রিয় ছিল। Google পরে সম্পূর্ণ নতুন ভাবে লেখা Angular আনে, যা AngularJS থেকে সরাসরি upgrade-যোগ্য ছিল না, আর AngularJS-এর দীর্ঘমেয়াদি সমর্থন ২০২১ সালের ডিসেম্বরের শেষে শেষ হয় বলে তাদের ঘোষণা। বহু দলকে পুরো frontend নতুন করে লিখতে হয়েছে। Framework মরেনি, কিন্তু তার একটি প্রজন্ম থেমেছে, যা ব্যবহারকারীর কাছে প্রায় একই।

উল্টো উদাহরণ Express. Express 4-এর পর পরবর্তী major version, Express 5, আসতে প্রায় এক দশক লেগেছে; শেষে ২০২৪ সালে প্রকাশিত হয়। এই দীর্ঘ সময়েও এটি বহু production অ্যাপে নির্ভরযোগ্যভাবে চলছিল। এই পর্বের registry-র হিসাবেও Express-এর গত বছরের release সংখ্যা কম, কিন্তু সাম্প্রতিক release আছে। ধীর release পরিপক্বতারও লক্ষণ হতে পারে।

তাই একা কোনো সংকেত যথেষ্ট নয়: লিখিত support policy, পুরোনো সমর্থিত লাইনে সময়মতো security fix, একাধিক রক্ষণাবেক্ষণকারী (একজনের প্রজেক্টের bus factor এক), migration guide, আর ecosystem-এর বড় library-গুলোর নতুন version সমর্থন, সব একসাথে পড়তে হয়।

Dependency-র স্বাস্থ্যও এই প্রশ্নের অংশ। ২০১৬ সালে npm-এ left-pad নামের একটি ছোট package তার লেখক সরিয়ে নিলে অনেক build একসাথে ভেঙে যায় বলে ব্যাপকভাবে জানা; এরপর npm package সরানোর নিয়ম কড়া করে। শিক্ষা: framework সুস্থ হলেও তার নিচের অসংখ্য ছোট package-এর স্বাস্থ্যও আপনার ঝুঁকি। Lockfile, নিয়মিত audit আর অপ্রয়োজনীয় dependency না রাখা এখানে সাহায্য করে (পর্ব ৫০)।

মূল উপলব্ধি: framework-এর স্বাস্থ্য একটি সংখ্যা নয়, কয়েকটি পাবলিক সংকেতের ছবি: লিখিত নীতি, নিয়মিত fix, একাধিক রক্ষণাবেক্ষণকারী আর upgrade-এর পথ। বছরে একবার এই ছবিটি আবার দেখুন।

অনুশীলন

হিসাব, পূর্বাভাস আর সমালোচনা; একটি কাজে নিজের সংখ্যা বসিয়ে কোড চালাতে হবে।

  1. ছকের হিসাব আর সংবেদনশীলতা: একটি internal admin tool-এর ছয়টি মাপকাঠির ওজন: team ৩৫, hosting ৫, speed ৩০, realtime ০, SEO ০, maintain ৩০. Django-র স্কোর ৫, ২, ৫, ৩, ৫, ৫; Laravel-এর ১, ৫, ৫, ৩, ৫, ৪. (ক) দুটির মোট স্কোর কত? (খ) team থেকে hosting-এ সর্বনিম্ন কত পূর্ণ পয়েন্ট সরালে Laravel কঠোরভাবে এগিয়ে যায়?

    (ক) Django: ৫×৩৫ + ২×৫ + ৫×৩০ + ৩×০ + ৫×০ + ৫×৩০ = ১৭৫ + ১০ + ১৫০ + ১৫০ = ৪৮৫, ÷ ১০০ = 4.85. Laravel: ১×৩৫ + ৫×৫ + ৫×৩০ + ০ + ০ + ৪×৩০ = ৩৫ + ২৫ + ১৫০ + ১২০ = ৩৩০, অর্থাৎ 3.30.

    (খ) প্রতি পয়েন্ট team থেকে hosting-এ সরালে Django-র মোট বদলায় −৫ + ২ = −৩, Laravel-এর −১ + ৫ = +৪; ব্যবধান কমে ৭ করে। শুরুর ব্যবধান ৪৮৫ − ৩৩০ = ১৫৫. ১৫৫ ÷ ৭ ≈ ২২.১. যাচাই: ২২ পয়েন্টে Django ৪১৯, Laravel ৪১৮, তখনো Django; ২৩ পয়েন্টে Django ৪১৬, Laravel ৪২২. উত্তর ২৩ পয়েন্ট, অর্থাৎ team-এর ওজন ৩৫ থেকে ১২-তে নামাতে হবে। এত বড় পরিবর্তন লাগে বলেই এই দৃশ্যপটে Django-র জয় মজবুত।

  2. ফল আগে বলুন: innovation token-এর মডেলে (বাজেট ৩; দল জানে react, typescript, express, postgresql, linux vps; প্রস্তাবে nextjs, react, typescript, prisma, postgresql মূল, আর trpc, mongodb, graphql, kubernetes মূল নয়) শুধু একটি বদল করা হলো: দলের জানা তালিকায় 'nextjs' যোগ। চালালে আউটপুটের ছয়টি লাইন কী হবে?

    নতুন জিনিস এখন prisma, trpc, mongodb, graphql, kubernetes, মোট পাঁচটি, যা বাজেটের বেশি। মূল নয় এমন নতুনগুলো বাদ গেলে থাকে শুধু prisma. সত্যিকারের run-এর আউটপুট:

    first proposal
    tokens 5/3: prisma, trpc, mongodb, graphql, kubernetes
    over budget, drop non-core new items: trpc, mongodb, graphql, kubernetes
    second proposal
    tokens 1/3: prisma
    within budget

    খেয়াল করুন, দল Next.js জানলে একটি token বাঁচে; একই প্রস্তাব দলভেদে ভিন্ন দামের।

  3. প্রস্তাবের সমালোচনা: পুরান ঢাকার মুদি দোকানের (একজন Laravel ফ্রিল্যান্সার, cPanel shared hosting-এ শুধু PHP আর MySQL, ছয় সপ্তাহ, SEO জরুরি) জন্য একজন পরামর্শক প্রস্তাব দিয়েছেন: “Next.js frontend, Go-তে তিনটি microservice (catalog, order, user), MongoDB, Redis, সব Kubernetes-এ, GraphQL gateway দিয়ে।” অন্তত পাঁচটি সমস্যা আর একটি বিকল্প প্রস্তাব লিখুন।
    • কঠিন শর্ত ভাঙে: shared hosting-এ Node, Go বা Kubernetes চলে না। প্রস্তাবটি আগে hosting বদলাতে বাধ্য করে, যা বাজেট আর মালিকের পরিচিত ব্যবস্থার বাইরে।
    • দলের সাথে অমিল: একজন Laravel ফ্রিল্যান্সারকে TypeScript, Go, MongoDB, GraphQL আর Kubernetes শিখতে হবে। Innovation token-এর হিসাবে অন্তত পাঁচ-ছয়টি token, বাজেট তিনের দ্বিগুণ।
    • Microservices অকারণ: তিনটি সেবার আলাদা চাপ বা আলাদা দল নেই; network-এর ব্যর্থতা, distributed transaction আর তিনটি deploy শুধু বোঝা বাড়ায়।
    • সময়: ছয় সপ্তাহে auth, admin আর অর্ডারের তালিকা নিজে বানাতে হবে, আর অবকাঠামো সাজাতেই সময় চলে যাবে।
    • রক্ষণাবেক্ষণ আর খরচ: বছরে কয়েকবার দেখা একজন মানুষের পক্ষে Kubernetes cluster, MongoDB আর Redis-এর update ও backup চালানো অবাস্তব।
    • ডেটার মডেল: order, stock আর টাকার হিসাবে transaction দরকার, যেখানে relational database স্বাভাবিক; MongoDB বাছার কোনো কারণ বলা নেই।

    বিকল্প: Laravel + Blade + MySQL, একটি monolith, shared hosting-এ; প্রয়োজনে Livewire দিয়ে cart-এর interactivity. ADR-এ “আবার ভাবব যদি” অংশে লিখুন: অর্ডার দিনে অনেক বাড়লে বা live feature লাগলে VPS-এ যাওয়ার কথা ভাবা হবে।

  4. খরচের মডেল বদলান: migration-এর খরচের মডেলে দুটি পরিবর্তন করুন: checkout ১০ থেকে ১৬ দিন, আর DEVS = 3. চালানোর আগে হাতে হিসাব করুন সবচেয়ে খারাপ পরিস্থিতি (tangled, new DB, no tests) কত dev-day আর কত সপ্তাহ হবে, তারপর চালিয়ে মিলিয়ে নিন।

    Module-এর যোগফল: ৮ + ৬ + ১৬ + ৭ + ১২ + ৫ = ৫৪. জট: ৫৪ × 1.6 = 86.4; ডেটা: + ১৫ = 101.4; যাচাই: × 1.35 = 136.89, গোল করে ১৩৭ dev-day. সপ্তাহ: ১৩৭ ÷ ৩ ÷ ৫ ≈ 9.13, মডেল লেখে ~9.1 weeks for 3 devs. চালালে পুরো আউটপুট:

    clean API, same DB, tests    63 dev-days  ~4.2 weeks for 3 devs
    clean API, new DB, tests     76 dev-days  ~5.1 weeks for 3 devs
    tangled, same DB, no tests  121 dev-days  ~8.1 weeks for 3 devs
    tangled, new DB, no tests   137 dev-days  ~9.1 weeks for 3 devs

    একটি সতর্কতা: মডেলটি ধরে নেয় তিনজন দুজনের চেয়ে ঠিক দেড় গুণ দ্রুত। বাস্তবে নতুন সদস্যের শেখার সময় আর সমন্বয়ের খরচ যোগ হয়, তাই আসল সময় সম্ভবত বেশি; Fred Brooks-এর “The Mythical Man-Month” (১৯৭৫) এই প্রশ্নেরই ক্লাসিক আলোচনা।

নিজেকে যাচাই করুন

ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।

ক্রমএকটি নতুন প্রজেক্টের stack বাছাইয়ের ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)

  1. দল, পণ্য, SEO, hosting, সময় আর রক্ষণাবেক্ষণের প্রশ্নের উত্তর লেখা
  2. কঠিন শর্ত দিয়ে অচল বিকল্প বাদ দেওয়া
  3. মাপকাঠির ওজন লিখে ফেলা
  4. টিকে থাকা বিকল্পকে স্কোর দিয়ে সংবেদনশীলতা দেখা
  5. ADR-এ সিদ্ধান্ত, পরিণাম আর “আবার ভাবব যদি” লেখা

তিনটি মাপকাঠির ওজন 40, 30, 30. Stack A-র স্কোর 5, 2, 4; Stack B-র 3, 5, 4. ওজন দেওয়া মোট স্কোর (÷ 100) অনুযায়ী ফল কী?

  • A জেতে, 3.80 বনাম 3.60
  • B জেতে, 3.90 বনাম 3.80
  • দুটি সমান, কারণ ওজনের হিসাবে ফল একই আসে
  • A জেতে, কারণ সবচেয়ে ভারী মাপকাঠিতে তার স্কোর বেশি

একটি ছোট দোকানের hosting cPanel shared hosting, যেখানে শুধু PHP আর MySQL চলে, Node বা Python অ্যাপের সুবিধা নেই। কোন stack বাড়তি সেবা ছাড়াই পুরো দোকান (cart আর অর্ডারসহ) চালাতে পারে?

  • Next.js SSR + Prisma
  • MERN + Socket.IO
  • Laravel + Blade + MySQL
  • Django + HTMX

একটি দল Express, PostgreSQL আর React আগে production-এ চালিয়েছে। প্রস্তাবিত stack: React, Express, PostgreSQL, Redis, GraphQL আর Kubernetes. Innovation token-এর ধারণায়, প্রতিটি অপরিচিত প্রযুক্তি একটি token হলে কয়টি token খরচ হচ্ছে?

  • ৩টি
  • ৬টি
  • ২টি
  • ০টি, কারণ সবগুলোই জনপ্রিয় প্রযুক্তি

একটি দল এক বছর আগে একটি Architecture Decision Record (ADR) লিখে MongoDB বেছেছিল। এখন তারা PostgreSQL-এ যেতে চায়। ADR-এর প্রচলিত রীতিতে কী করা উচিত?

  • পুরোনো ADR মুছে ফেলা
  • পুরোনো ADR-এর সিদ্ধান্তের অংশে MongoDB কেটে PostgreSQL লেখা
  • কিছু না করা, কারণ ADR শুধু শুরুর জন্য
  • নতুন একটি ADR লিখে পুরোনোটিকে “প্রতিস্থাপিত” চিহ্নিত করা

পাঁচ বছর চলবে এমন একটি অ্যাপের জন্য framework বাছতে কোন সংকেতটি সবচেয়ে কাজের?

  • GitHub-এ star-এর সংখ্যা
  • তারিখসহ লিখিত support policy আর LTS, আর পুরোনো লাইনে সাম্প্রতিক security fix
  • গত মাসে সবচেয়ে বেশি release হয়েছে কোনটির
  • কোনটি নিয়ে সবচেয়ে বেশি blog লেখা হয়েছে

“Modular monolith” কথাটি কোনটিকে সবচেয়ে ঠিকভাবে বর্ণনা করে?

  • প্রতিটি module আলাদা server-এ deploy হয় আর HTTP-তে কথা বলে
  • একটি deploy, যেখানে যেকোনো কোড যেকোনো টেবিল সরাসরি বদলাতে পারে
  • একটি deploy, ভেতরে module-গুলো শুধু ঘোষিত interface দিয়ে যোগাযোগ করে
  • Frontend আর backend আলাদা repository-তে রাখা

শব্দকোষ

লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন, অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:

মনে রাখুন

  1. সেরা stack নেই, আছে পরিস্থিতির জন্য ভালো stack; আগে দল, পণ্য, SEO, hosting, সময় আর রক্ষণাবেক্ষণের প্রশ্ন।
  2. কঠিন শর্ত আগে, স্কোর পরে; ওজন স্কোরের আগে লিখুন আর সংবেদনশীলতা দেখুন।
  3. Monolith দিয়ে শুরু, ভেতরে module-এর দেয়াল; ডেটাবেসে কারণ না থাকলে PostgreSQL, hosting-এ শুধু MySQL থাকলে MySQL.
  4. Innovation token সীমিত: নতুন প্রযুক্তি সেখানেই, যেখানে তা পণ্যের মূল সুবিধা দেয়।
  5. দরজা খোলা রাখুন: পরিষ্কার API, standard database, test আর এক পাতার ADR; framework-এর স্বাস্থ্য পড়ুন লিখিত নীতি থেকে, star থেকে নয়।

পরের পর্বে: Stack বাছা হলো। এবার কোড লেখার কাজে AI কতটা ভরসার? পর্ব ৮৬-এ AI দিয়ে ফুল-স্ট্যাক: কোড লেখানো, review আর যাচাই।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

এই পর্বটি শেয়ার করুন:
এই পর্বে ভুল পেয়েছেন? জানান