Clean Architecture در یک سرویس ساده Node.js 🧱
یکی از مشکلهای همیشگی پروژههای وب این است که بعد از چند ماه، همهچیز توی یک فایل یا یک لایه قاطی میشود: route منطق بیزینسی دارد، مستقیم به DB وصل میشود و تست گرفتن هم کابوس میشود.
اینجا جایی است که ایدهٔ Clean Architecture بهدرد میخورد: جداکردن منطق بیزینسی از زیرساخت (مثل Express، DB، HTTP، و غیره) تا کد قابلتست و قابلتوسعه بماند. 🎯
در سادهترین حالت، فقط همین اصل را رعایت کنید:
Use Case / Domain لایهٔ مرکزی ➜ Framework و DB در لبهها
یعنی:
• Route فقط ورودی/خروجی HTTP را مدیریت کند ✅
• منطق اصلی در یک Service یا Use Case مستقل باشد ✅
• Service هیچ وابستگی مستقیم به Express یا driver خاص DB نداشته باشد ✅
یک نمونهٔ خیلی ساده در Node.js + Express:
حالا لایهٔ زیرساخت (Express + یک repo ساده):
چند نکتهٔ عملی از تجربهٔ پروژههای واقعی 🌱
• منطق اصلی را همیشه در Service / Use Case نگه دارید، نه داخل controller / route.
• وابستگیها را بهسمت لبهها ببرید؛ Domain نباید Express، HTTP status code یا driver خاص DB را بشناسد.
• این ساختار روی Next.js API Routes، Nest.js، Laravel و Django هم کاملاً قابلپیادهسازی است.
برای مطالعهٔ عمیقتر ایدهها:
Layered Architecture - Martin Fowler
Refactoring.Guru - Design Patterns
همانقدر که پروژه بزرگتر میشود، همین جداسازی ساده بین Domain و Infrastructure میتواند نجاتدهنده باشد. دفعهٔ بعدی که یک feature جدید مینویسید، از همین الگوی کوچک شروع کنید و قدمبهقدم کد را تمیزتر نگه دارید. 🚀
🔖 #Web #وب #Frontend #Backend #Clean_Architecture #Node_js #Express #Design_Patterns #Web_Development #Backend #Refactoring
👤 Developix
💎 Channel: @DevelopixWeb
یکی از مشکلهای همیشگی پروژههای وب این است که بعد از چند ماه، همهچیز توی یک فایل یا یک لایه قاطی میشود: route منطق بیزینسی دارد، مستقیم به DB وصل میشود و تست گرفتن هم کابوس میشود.
اینجا جایی است که ایدهٔ Clean Architecture بهدرد میخورد: جداکردن منطق بیزینسی از زیرساخت (مثل Express، DB، HTTP، و غیره) تا کد قابلتست و قابلتوسعه بماند. 🎯
در سادهترین حالت، فقط همین اصل را رعایت کنید:
Use Case / Domain لایهٔ مرکزی ➜ Framework و DB در لبهها
یعنی:
• Route فقط ورودی/خروجی HTTP را مدیریت کند ✅
• منطق اصلی در یک Service یا Use Case مستقل باشد ✅
• Service هیچ وابستگی مستقیم به Express یا driver خاص DB نداشته باشد ✅
یک نمونهٔ خیلی ساده در Node.js + Express:
// userService.js (لایه Domain / Use Case)
class UserService {
constructor(userRepo) {
this.userRepo = userRepo; // وابستگی به interface، نه به Express
}
async registerUser(data) {
const { email, password } = data;
if (!email || !password) {
throw new Error("Invalid data");
}
const exists = await this.userRepo.findByEmail(email);
if (exists) {
throw new Error("Email already used");
}
// اینجا میتوانید hashing، ruleها و ... را قرار دهید
return this.userRepo.create({ email, password });
}
}
module.exports = UserService;
حالا لایهٔ زیرساخت (Express + یک repo ساده):
// userRepo.js (لایه Infrastructure)
const users = [];
module.exports = {
async findByEmail(email) {
return users.find(u => u.email === email) || null;
},
async create(user) {
users.push(user);
return user;
}
};
// routes.js
const express = require("express");
const UserService = require("./userService");
const userRepo = require("./userRepo");
const router = express.Router();
const userService = new UserService(userRepo);
router.post("/register", async (req, res) => {
try {
const user = await userService.registerUser(req.body);
res.status(201).json(user);
} catch (err) {
res.status(400).json({ error: err.message });
}
});
module.exports = router;
چند نکتهٔ عملی از تجربهٔ پروژههای واقعی 🌱
• منطق اصلی را همیشه در Service / Use Case نگه دارید، نه داخل controller / route.
• وابستگیها را بهسمت لبهها ببرید؛ Domain نباید Express، HTTP status code یا driver خاص DB را بشناسد.
• این ساختار روی Next.js API Routes، Nest.js، Laravel و Django هم کاملاً قابلپیادهسازی است.
برای مطالعهٔ عمیقتر ایدهها:
Layered Architecture - Martin Fowler
Refactoring.Guru - Design Patterns
همانقدر که پروژه بزرگتر میشود، همین جداسازی ساده بین Domain و Infrastructure میتواند نجاتدهنده باشد. دفعهٔ بعدی که یک feature جدید مینویسید، از همین الگوی کوچک شروع کنید و قدمبهقدم کد را تمیزتر نگه دارید. 🚀
🔖 #Web #وب #Frontend #Backend #Clean_Architecture #Node_js #Express #Design_Patterns #Web_Development #Backend #Refactoring
👤 Developix
💎 Channel: @DevelopixWeb
❤1
تو خیلی از پروژههای وب، مخصوصاً وقتی React / Vue / Angular کار میکنی، نیاز به یک backend ساده برای تست و توسعه داری؛ چیزی که سریع بالا بیاد، JSON برگردونه و دردسر config زیاد هم نداشته باشه. اینجا Express دقیقاً همون چیزیه که لازم داری. 😎
این مطلب بر پایه داکیومنت رسمی Express نوشته شده:
Express Hello World
✅ ایده کلی
یک REST API خیلی مینیمال میسازیم که:
• با Node.js + Express راه میافته.
• یک endpoint مثل
• آماده است که از frontend (مثلاً با fetch در React) صداش بزنی.
۱) نصب اولیه پروژه
داخل یک فولدر خالی این دستورها رو اجرا کن:
۲) ساخت سرور ساده Express
فایلی به اسم
۳) اجرای سرور
داخل ترمینال:
حالا روی آدرس:
یک آرایه از userها میبینی.
برای تست سریع میتونی از Postman یا Insomnia استفاده کنی، یا حتی با fetch از سمت frontend صداش بزنی.
چرا این کار عملی و مهمه؟
• موقع توسعه frontend لازم نیست صبر کنی backend اصلی تیم آماده بشه.
• میتونی شکل دقیق JSON رو خودت کنترل کنی.
• برای تمرین مفاهیم REST (GET/POST، status codeها، error handling) عالیه.
کد رو بردار، روی سیستم خودت اجراش کن و کمکم endpointهای جدید مثل
🔖 #Web #وب #Frontend #Backend #Node_js #Express #API #Backend #Frontend #JavaScript #Web_Dev
👤 Developix
💎 Channel: @DevelopixWeb
این مطلب بر پایه داکیومنت رسمی Express نوشته شده:
Express Hello World
✅ ایده کلی
یک REST API خیلی مینیمال میسازیم که:
• با Node.js + Express راه میافته.
• یک endpoint مثل
/api/users برمیگردونه.• آماده است که از frontend (مثلاً با fetch در React) صداش بزنی.
۱) نصب اولیه پروژه
داخل یک فولدر خالی این دستورها رو اجرا کن:
npm init -y
npm install express cors
۲) ساخت سرور ساده Express
فایلی به اسم
server.js بساز و این کد رو داخلش بذار:const express = require('express');
const cors = require('cors');
const app = express();
const PORT = 4000;
app.use(cors());
app.use(express.json());
// GET /api/users
app.get('/api/users', (req, res) => {
const users = [
{ id: 1, name: 'Ali', role: 'admin' },
{ id: 2, name: 'Sara', role: 'user' },
];
res.json(users);
});
// POST /api/users
app.post('/api/users', (req, res) => {
const newUser = req.body;
if (!newUser.name) {
return res.status(400).json({ message: 'name لازم است' });
}
newUser.id = Date.now();
res.status(201).json(newUser);
});
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});۳) اجرای سرور
داخل ترمینال:
node server.js
حالا روی آدرس:
http://localhost:4000/api/users
یک آرایه از userها میبینی.
برای تست سریع میتونی از Postman یا Insomnia استفاده کنی، یا حتی با fetch از سمت frontend صداش بزنی.
چرا این کار عملی و مهمه؟
• موقع توسعه frontend لازم نیست صبر کنی backend اصلی تیم آماده بشه.
• میتونی شکل دقیق JSON رو خودت کنترل کنی.
• برای تمرین مفاهیم REST (GET/POST، status codeها، error handling) عالیه.
کد رو بردار، روی سیستم خودت اجراش کن و کمکم endpointهای جدید مثل
/api/products یا /api/auth/login اضافه کن. هرچی زودتر یک API واقعی زیر دستت داشته باشی، سرعت رشدت در web dev چند برابر میشه. 🚀🔖 #Web #وب #Frontend #Backend #Node_js #Express #API #Backend #Frontend #JavaScript #Web_Dev
👤 Developix
💎 Channel: @DevelopixWeb
ساختن یک API کوچک و تمیز با Node.js و Express از اون کارهاییه که مستقیم توی پروژههای واقعی به کار میاد؛ از اتصال React/Vue گرفته تا ساخت پنل ادمین یا حتی یه سرویس موبایل.
این مدل API رو میشه دقیقاً بر اساس داک رسمی Express جلو برد:
https://expressjs.com/en/starter/hello-world.html
ایدهمون 👇
یه REST API خیلی ساده برای مدیریت tasks میسازیم که از سمت Frontend (مثلاً React) قابل مصرف باشه:
• گرفتن لیست tasks
• اضافه کردن task جدید
نکته خوبش اینه که هم با ساختار یک Express app آشنا میشی، هم میفهمی چطور JSON رو هندل کنی و پاسخ استاندارد بدی.
اول باید Node.js نصب باشه. بعد توی یه فولدر خالی این کامندها رو بزن:
حالا فایل
حالا:
• با
• توی مرورگر برو به
• برای تست
این ساختار کوچیک، پایه خیلی از پروژههای جدیتره:
• میتونی بعداً auth اضافه کنی.
• میتونی به جای آرایه، از MongoDB یا PostgreSQL استفاده کنی.
• میتونی همین API رو به یه React یا Vue app وصل کنی و یه Todo ساده ولی تمیز بسازی.
امتحانش کن، سرور رو بالا بیار و یه بار واقعی باهاش دیتا رد و بدل کن؛ از اون چیزهاییست که بعدش کار با Backend خیلی طبیعیتر به نظر میرسه. اگر مفید بود، برای بقیه همتیمیها هم بفرست تا همه روی یک استک مشترک تمرین کنید.
🔖 #Web #وب #Frontend #Backend #Node_js #Express #REST_API #Backend #Frontend #JavaScript #Web_Development #Tutorial
👤 Developix
💎 Channel: @DevelopixWeb
این مدل API رو میشه دقیقاً بر اساس داک رسمی Express جلو برد:
https://expressjs.com/en/starter/hello-world.html
ایدهمون 👇
یه REST API خیلی ساده برای مدیریت tasks میسازیم که از سمت Frontend (مثلاً React) قابل مصرف باشه:
• گرفتن لیست tasks
• اضافه کردن task جدید
نکته خوبش اینه که هم با ساختار یک Express app آشنا میشی، هم میفهمی چطور JSON رو هندل کنی و پاسخ استاندارد بدی.
اول باید Node.js نصب باشه. بعد توی یه فولدر خالی این کامندها رو بزن:
npm init -y
npm install express cors
حالا فایل
index.js رو بساز و این کد رو بذار داخلش:const express = require("express");
const cors = require("cors");
const app = express();
const PORT = 3000;
app.use(cors());
app.use(express.json());
let tasks = [
{ id: 1, title: "Learn Express", done: false },
{ id: 2, title: "Build a simple API", done: false }
];
// GET /api/tasks
app.get("/api/tasks", (req, res) => {
res.json(tasks);
});
// POST /api/tasks
app.post("/api/tasks", (req, res) => {
const { title } = req.body;
if (!title) {
return res.status(400).json({ error: "title is required" });
}
const newTask = {
id: tasks.length + 1,
title,
done: false
};
tasks.push(newTask);
res.status(201).json(newTask);
});
app.listen(PORT, () => {
console.log(`Server is running on http://localhost:${PORT}`);
});حالا:
• با
node index.js سرور رو بالا بیار.• توی مرورگر برو به
http://localhost:3000/api/tasks، باید یه آرایه JSON ببینی.• برای تست
POST از Postman یا افزونه REST Client یا حتی fetch در Frontend استفاده کن.این ساختار کوچیک، پایه خیلی از پروژههای جدیتره:
• میتونی بعداً auth اضافه کنی.
• میتونی به جای آرایه، از MongoDB یا PostgreSQL استفاده کنی.
• میتونی همین API رو به یه React یا Vue app وصل کنی و یه Todo ساده ولی تمیز بسازی.
امتحانش کن، سرور رو بالا بیار و یه بار واقعی باهاش دیتا رد و بدل کن؛ از اون چیزهاییست که بعدش کار با Backend خیلی طبیعیتر به نظر میرسه. اگر مفید بود، برای بقیه همتیمیها هم بفرست تا همه روی یک استک مشترک تمرین کنید.
🔖 #Web #وب #Frontend #Backend #Node_js #Express #REST_API #Backend #Frontend #JavaScript #Web_Development #Tutorial
👤 Developix
💎 Channel: @DevelopixWeb
❤3
در نمونهکد بالا در نسخهی اول هر درخواست HTTP یک connection جدید به دیتابیس باز میکند و با هر کوئری یک round-trip اضافه به MySQL میزند. این الگو هم روی Performance (بهخصوص در ترافیک بالا) اثر منفی دارد، هم ریسک Connection Exhaustion را بالا میبرد. در نسخهی بهینه با استفاده از Connection Pooling و اجرای کوئریهای وابسته در قالب یک Transaction، هم تعداد round-tripها کم شده، هم ثبات دادهها حفظ میشود.
اگر در یک Web API Node.js با mysql2 یا هر Driver مشابه کار میکنید، بهتر است به جای باز کردن connection در هر handler، در لایهی Infrastructure یک pool مشترک بسازید و در handlerها فقط از آن pool borrow کنید؛ این کار هم مقیاسپذیری سرویس را بهتر میکند، هم در شرایط ترافیک سنگین فشار روی دیتابیس و OS را کاهش میدهد.
برای مطالعهی بیشتر دربارهی Connection Pooling در Node.js میتوانید مستندات رسمی mysql2 را ببینید.
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb
اگر در یک Web API Node.js با mysql2 یا هر Driver مشابه کار میکنید، بهتر است به جای باز کردن connection در هر handler، در لایهی Infrastructure یک pool مشترک بسازید و در handlerها فقط از آن pool borrow کنید؛ این کار هم مقیاسپذیری سرویس را بهتر میکند، هم در شرایط ترافیک سنگین فشار روی دیتابیس و OS را کاهش میدهد.
برای مطالعهی بیشتر دربارهی Connection Pooling در Node.js میتوانید مستندات رسمی mysql2 را ببینید.
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb
👍4❤1
Forwarded from BehinSMS (Taknet support)
Please open Telegram to view this post
VIEW IN TELEGRAM
وقتی روی فرم جستجو هر keypress مستقیماً درخواست به سرور بفرستد، هم backend تحت فشار میرود هم UI کند میشود. یک الگوی ساده با debounce کمک میکند فقط وقتی کاربر چند لحظه تایپ را متوقف کرد، درخواست زده شود. 🔎
ایده این است: هر بار کاربر تایپ میکند، یک timeout قبلی لغو میشود و یک جدید تنظیم میشود. اگر تا مثلاً ۴۰۰ms چیزی تایپ نشد، تابع واقعی اجرا میشود (فراخوانی API، فیلتر لیست و ...).
✅ نتیجه:
- درخواستهای کمتر به سرور
- UI روانتر
- کد تمیزتر نسبت به if/elseهای تکراری روی eventها
یک پیادهسازی ساده و عمومی در JS:
بهتر است delay را بر اساس نوع ورودی تنظیم شود؛ برای جستجوی live معمولاً بین ۳۰۰ تا ۵۰۰ms معقول است. در UIهای سنگین (لیستهای بزرگ، نمودارها و ...) debounce میتواند تفاوت محسوسی در performance ایجاد کند. 🚀
برای مطالعه بیشتر درباره الگوهای بهینهسازی eventها و performance در مرورگر:
MDN - Debouncing events
امتحان روی یک input ساده در پروژه فعلی کافی است تا تاثیرش روی روان بودن تجربه کاربری دیده شود. 😉
🔖 #Web #وب #Frontend #Backend #debounce #javascript #frontend #performance #web_dev
👤 Developix
💎 Channel: @DevelopixWeb
ایده این است: هر بار کاربر تایپ میکند، یک timeout قبلی لغو میشود و یک جدید تنظیم میشود. اگر تا مثلاً ۴۰۰ms چیزی تایپ نشد، تابع واقعی اجرا میشود (فراخوانی API، فیلتر لیست و ...).
✅ نتیجه:
- درخواستهای کمتر به سرور
- UI روانتر
- کد تمیزتر نسبت به if/elseهای تکراری روی eventها
یک پیادهسازی ساده و عمومی در JS:
function debounce(fn, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
const searchInput = document.querySelector('#search');
function handleSearch(e) {
const q = e.target.value.trim();
if (!q) return;
// call API, fetch data, etc.
console.log('Searching for:', q);
}
const debouncedSearch = debounce(handleSearch, 400);
searchInput.addEventListener('input', debouncedSearch);
بهتر است delay را بر اساس نوع ورودی تنظیم شود؛ برای جستجوی live معمولاً بین ۳۰۰ تا ۵۰۰ms معقول است. در UIهای سنگین (لیستهای بزرگ، نمودارها و ...) debounce میتواند تفاوت محسوسی در performance ایجاد کند. 🚀
برای مطالعه بیشتر درباره الگوهای بهینهسازی eventها و performance در مرورگر:
MDN - Debouncing events
امتحان روی یک input ساده در پروژه فعلی کافی است تا تاثیرش روی روان بودن تجربه کاربری دیده شود. 😉
🔖 #Web #وب #Frontend #Backend #debounce #javascript #frontend #performance #web_dev
👤 Developix
💎 Channel: @DevelopixWeb
👍3❤2
Forwarded from کانال رسمی تک نت | Taknet
سرور اختصاصی تکنت؛ تحویل فوری، بدون قطعی ✅
🔹 پورت اختصاصی واقعی
🔹 آپلود رایگان
🔹 آپتایم 99.99% تضمینی
🔹 ارائه IP مازاد
🔹 پشتیبانی 24/7 (تیکت + آنلاین)
🔹 نصب سریع
🔹 پرداخت ماهیانه
⏳ ظرفیت محدود — همین الان تماس بگیر و سرویس رو رزرو کن:
📞 02191555530
🔗 https://taknet.ir/services/dedicated-server
🔹 پورت اختصاصی واقعی
🔹 آپلود رایگان
🔹 آپتایم 99.99% تضمینی
🔹 ارائه IP مازاد
🔹 پشتیبانی 24/7 (تیکت + آنلاین)
🔹 نصب سریع
🔹 پرداخت ماهیانه
⏳ ظرفیت محدود — همین الان تماس بگیر و سرویس رو رزرو کن:
📞 02191555530
🔗 https://taknet.ir/services/dedicated-server
Forwarded from ابر ویراک
ویراک کلود | تجربهی ابری بدون محدودیت ☁️🚀
🎁 ۲۰٪ شارژ هدیه روی اولین واریزی
مزیتهایی که واقعاً فرق میسازن:
⚡️ پهنای باند 980 مگ
🌐با IP مازاد
⏱️ راهاندازی فوری
💳 پرداخت ساعتی
🛡 پشتیبانی ۲۴/۷
💬 هر سوالی داشتی، تیم ما کنارتـه
✅ مناسب استارتاپها، تیمهای فنی، تا سازمانهای بزرگ
همین الان شروع کن و با حداکثر منابع، سریعتر رشد کن 👇🏻
📞 تماس سریع: 02191555530
🔗 https://virakcloud.com
🎁 ۲۰٪ شارژ هدیه روی اولین واریزی
مزیتهایی که واقعاً فرق میسازن:
⚡️ پهنای باند 980 مگ
🌐با IP مازاد
⏱️ راهاندازی فوری
💳 پرداخت ساعتی
🛡 پشتیبانی ۲۴/۷
💬 هر سوالی داشتی، تیم ما کنارتـه
✅ مناسب استارتاپها، تیمهای فنی، تا سازمانهای بزرگ
همین الان شروع کن و با حداکثر منابع، سریعتر رشد کن 👇🏻
📞 تماس سریع: 02191555530
🔗 https://virakcloud.com
✨ NextAuth.js؛ احراز هویت مدرن برای Next.js
اگه با Next.js کار میکنی و احراز هویت همیشه برات دردسر بوده، NextAuth.js دقیقا برای همینه 👇
🔐 چیه و چی حل میکنه؟
یک کتابخونهٔ آماده برای اضافهکردن login/signup، session management و OAuth (مثل Google, GitHub, Twitter) بدون اینکه خودت از صفر Token و Cookie و Security رو هندل کنی.
🚀 ویژگیهای مهم
• پشتیبانی از OAuth, Email/Password, Credentials
• Session سمت سرور، سازگار با SSR و Route Handlerهای Next.js
• تنظیمات قابلانعطاف و TypeScript‑friendly
• کار با DBهای مختلف (PostgreSQL, MySQL, MongoDB, Prisma و ...)
🛠️ نصب سریع
مثال ساده Route Handler در Next.js 13+
برای پروژههای SaaS، پنلهای ادمین یا هر اپ multi-user، استفاده از NextAuth.js هم سریعتره هم امنتر از نوشتن auth از صفر ✅
Docs رسمی:
https://next-auth.js.org
GitHub:
https://github.com/nextauthjs/next-auth
امتحانش کن و روی auth وقت کمتری بذار تا روی featureهای اصلی اپ 😉
🔖 #Web #وب #Frontend #Backend #NextAuth #Next_js #Authentication #OAuth #Web_Dev #JavaScript #TypeScript
👤 Developix
💎 Channel: @DevelopixWeb
اگه با Next.js کار میکنی و احراز هویت همیشه برات دردسر بوده، NextAuth.js دقیقا برای همینه 👇
🔐 چیه و چی حل میکنه؟
یک کتابخونهٔ آماده برای اضافهکردن login/signup، session management و OAuth (مثل Google, GitHub, Twitter) بدون اینکه خودت از صفر Token و Cookie و Security رو هندل کنی.
🚀 ویژگیهای مهم
• پشتیبانی از OAuth, Email/Password, Credentials
• Session سمت سرور، سازگار با SSR و Route Handlerهای Next.js
• تنظیمات قابلانعطاف و TypeScript‑friendly
• کار با DBهای مختلف (PostgreSQL, MySQL, MongoDB, Prisma و ...)
🛠️ نصب سریع
npm install next-auth
مثال ساده Route Handler در Next.js 13+
import NextAuth from "next-auth";
import GitHubProvider from "next-auth/providers/github";
export const authOptions = {
providers: [
GitHubProvider({
clientId: process.env.GITHUB_ID,
clientSecret: process.env.GITHUB_SECRET,
}),
],
};
const handler = NextAuth(authOptions);
export { handler as GET, handler as POST };
برای پروژههای SaaS، پنلهای ادمین یا هر اپ multi-user، استفاده از NextAuth.js هم سریعتره هم امنتر از نوشتن auth از صفر ✅
Docs رسمی:
https://next-auth.js.org
GitHub:
https://github.com/nextauthjs/next-auth
امتحانش کن و روی auth وقت کمتری بذار تا روی featureهای اصلی اپ 😉
🔖 #Web #وب #Frontend #Backend #NextAuth #Next_js #Authentication #OAuth #Web_Dev #JavaScript #TypeScript
👤 Developix
💎 Channel: @DevelopixWeb
در نمونهکد بالا، در نسخهٔ اشتباه همهٔ event listenerها روی window ثبت میشوند اما هرگز در زمان نیاز حذف نمیشوند و همین موضوع میتواند در یک Single Page Application بزرگ باعث Memory Leak و افت کارایی در طول زمان شود. در نسخهٔ اصلاحشده با نگه داشتن reference توابع هندلر و حذف آنها در زمان مناسب، ضمن رعایت best practice در مدیریت lifecycle، از رشد بیرویهٔ مصرف مموری و کند شدن رندر جلوگیری میشود. در پروژههای جدی وب، مخصوصاً وقتی کامپوننتها بهطور پویا mount/unmount میشوند، مدیریت صحیح event listenerها مثل این نمونه بسیار حیاتی است.
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb
🚀 ترفند کوچک برای لود سریعتر JS با
خیلی وقتها اسکریپتهای سنگین باعث میشوند لود اولیه صفحه کند شود و First Paint دیر اتفاق بیفته. یک راه ساده و امن برای بهتر شدن تجربه کاربر، استفاده از attribute بهدردبخور
وقتی روی <script> از
- HTML بدون توقف پارس میشود ✅
- فایل JS در پسزمینه دانلود میشود ✅
- اجرای JS بعد از کامل شدن HTML و قبل از
برخلاف
مرجع بیشتر: MDN – <script> element
یک بار روی اسکریپتهای عمومی و analytics امتحان شود، تاثیرش روی سرعت حس میشود. ⚡️
🔖 #Web #وب #Frontend #Backend #HTML #script #defer #Performance #Frontend #Web
👤 Developix
💎 Channel: @DevelopixWeb
deferخیلی وقتها اسکریپتهای سنگین باعث میشوند لود اولیه صفحه کند شود و First Paint دیر اتفاق بیفته. یک راه ساده و امن برای بهتر شدن تجربه کاربر، استفاده از attribute بهدردبخور
defer در اسکریپتهای خارجی است. 😎وقتی روی <script> از
defer استفاده میشود:- HTML بدون توقف پارس میشود ✅
- فایل JS در پسزمینه دانلود میشود ✅
- اجرای JS بعد از کامل شدن HTML و قبل از
DOMContentLoaded انجام میشود ✅<!-- خوب برای اسکریپتهای غیرضروری در لحظه اول -->
<script src="/static/js/app.js" defer></script>
<!-- اگر به ترتیب اجرا نیاز داری، همین ترتیب tagها رعایت میشود -->
<script src="/static/js/vendor.js" defer></script>
<script src="/static/js/main.js" defer></script>
برخلاف
async، ترتیب اجرای اسکریپتها با defer حفظ میشود، که برای بیشتر پروژههای Web امنتر و قابلپیشبینیتر است. 🌱مرجع بیشتر: MDN – <script> element
یک بار روی اسکریپتهای عمومی و analytics امتحان شود، تاثیرش روی سرعت حس میشود. ⚡️
🔖 #Web #وب #Frontend #Backend #HTML #script #defer #Performance #Frontend #Web
👤 Developix
💎 Channel: @DevelopixWeb
👍3
تمیز کردن Controller با تکنیک Extract Function 🧹
یکی از سادهترین و تاثیرگذارترین تکنیکهای refactor در وب، مخصوصاً توی backend، Extract Function هست: جدا کردن بخشهای منطقیِ یک تابع بزرگ به چند تابع کوچک، واضح و قابل تست. 👌
وقتی یک controller یا handler همهچیز را خودش انجام میدهد (validation، لاگ، query، mapping، ارسال response)، سریع تبدیل به کد شلوغ و سختقابلتغییر میشود؛ همون چیزی که تو Clean Code بهش میگن God Function یا Long Method.
بیایید یک مثال Node.js & Express ببینیم.
قبل از Extract Function (کد شلوغ)
این تابع "کار میکند"، اما:
• چندین سطح responsibility قاطی شده 🔥
• تست کردنش سختتر است
• توسعه بعدی (مثل اضافهکردن audit log یا event) ریسک bug دارد
بعد از Extract Function (کد تمیزتر)
الان هر تابع یک کار مشخص انجام میدهد:
•
•
•
چند مزیت مهم:
• تست واحد برای validation و منطقِ وجود کاربر مستقل از Express ✅
• خوانایی خیلی بهتر؛ controller مثل یک سناریو step-by-step شده 📖
• آماده برای reuse در endpoint یا سرویسهای دیگر ♻️
برای مطالعه بیشتر درباره Extract Function و refactoring:
refactoring.guru/extract-method
این نوع refactorهای کوچک، در طول زمان معماری backend و حتی frontend (مثلاً در handlerهای React/Next.js) را بسیار تمیزتر و قابلنگهداریتر میکند. امروز روی یک متد شلوغ امتحانش کنید و تفاوت را در خوانایی حس کنید. 🚀
🔖 #Web #وب #Frontend #Backend #refactoring #clean_code #nodejs #express #backend #extract_function #controller
👤 Developix
💎 Channel: @DevelopixWeb
یکی از سادهترین و تاثیرگذارترین تکنیکهای refactor در وب، مخصوصاً توی backend، Extract Function هست: جدا کردن بخشهای منطقیِ یک تابع بزرگ به چند تابع کوچک، واضح و قابل تست. 👌
وقتی یک controller یا handler همهچیز را خودش انجام میدهد (validation، لاگ، query، mapping، ارسال response)، سریع تبدیل به کد شلوغ و سختقابلتغییر میشود؛ همون چیزی که تو Clean Code بهش میگن God Function یا Long Method.
بیایید یک مثال Node.js & Express ببینیم.
قبل از Extract Function (کد شلوغ)
app.post('/api/users', async (req, res) => {
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ message: 'Invalid data' });
}
console.log('Creating user', email);
const exists = await User.findOne({ email });
if (exists) {
return res.status(409).json({ message: 'User exists' });
}
const hash = await bcrypt.hash(password, 10);
const user = await User.create({ email, password: hash });
return res.status(201).json({
id: user.id,
email: user.email,
});
});این تابع "کار میکند"، اما:
• چندین سطح responsibility قاطی شده 🔥
• تست کردنش سختتر است
• توسعه بعدی (مثل اضافهکردن audit log یا event) ریسک bug دارد
بعد از Extract Function (کد تمیزتر)
function validateCreateUser(body) {
const { email, password } = body;
if (!email || !password) {
throw new Error('INVALID_DATA');
}
}
async function ensureUserNotExists(email) {
const exists = await User.findOne({ email });
if (exists) {
throw new Error('USER_EXISTS');
}
}
async function createUser(email, password) {
const hash = await bcrypt.hash(password, 10);
return User.create({ email, password: hash });
}
app.post('/api/users', async (req, res) => {
try {
validateCreateUser(req.body);
const { email, password } = req.body;
await ensureUserNotExists(email);
const user = await createUser(email, password);
return res.status(201).json({
id: user.id,
email: user.email,
});
} catch (err) {
if (err.message === 'INVALID_DATA') {
return res.status(400).json({ message: 'Invalid data' });
}
if (err.message === 'USER_EXISTS') {
return res.status(409).json({ message: 'User exists' });
}
return res.status(500).json({ message: 'Server error' });
}
});الان هر تابع یک کار مشخص انجام میدهد:
•
validateCreateUser → فقط validation•
ensureUserNotExists → فقط چک کردن business rule•
createUser → فقط ساختن userچند مزیت مهم:
• تست واحد برای validation و منطقِ وجود کاربر مستقل از Express ✅
• خوانایی خیلی بهتر؛ controller مثل یک سناریو step-by-step شده 📖
• آماده برای reuse در endpoint یا سرویسهای دیگر ♻️
برای مطالعه بیشتر درباره Extract Function و refactoring:
refactoring.guru/extract-method
این نوع refactorهای کوچک، در طول زمان معماری backend و حتی frontend (مثلاً در handlerهای React/Next.js) را بسیار تمیزتر و قابلنگهداریتر میکند. امروز روی یک متد شلوغ امتحانش کنید و تفاوت را در خوانایی حس کنید. 🚀
🔖 #Web #وب #Frontend #Backend #refactoring #clean_code #nodejs #express #backend #extract_function #controller
👤 Developix
💎 Channel: @DevelopixWeb
👍3❤1
در کد زیر سعی شده در یک route مربوط به Express دادهها از یک API خارجی گرفته شده و به صورت JSON برگردانده شود، اما یک اشتباه/Anti Pattern جدی در استفاده از async/await و مدیریت error وجود دارد که میتواند باعث رفتارهای غیرقابل پیشبینی روی سرور شود.
با دقت به این کد نگاه کنید:
چه چیزی باید در این کد اصلاح شود تا استفاده از async/await و مدیریت خطا به شکل درست و قابل پیشبینی انجام شود؟
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb
با دقت به این کد نگاه کنید:
app.get('/posts', async (req, res) => {
try {
const response = fetch('https://example.com/api/posts');
response
.then(r => r.json())
.then(data => {
res.json({
success: true,
posts: data
});
})
.catch(err => {
console.error('Fetch error:', err);
res.status(500).json({ message: 'Internal error' });
});
} catch (err) {
console.error('Route error:', err);
res.status(500).json({ message: 'Route failed' });
}
});چه چیزی باید در این کد اصلاح شود تا استفاده از async/await و مدیریت خطا به شکل درست و قابل پیشبینی انجام شود؟
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb
اسکرول صفحات روی موبایل اگه کلی event listener مثل
به طور پیشفرض، مرورگر مجبور میشه صبر کنه ببینه توی handler از
هر جا فقط میخوای event رو بخونی و قصد
مرجع: MDN - Passive event listeners
🔖 #Web #وب #Frontend #Backend #JavaScript #Performance #Frontend #Scroll #Event_Listener
👤 Developix
💎 Channel: @DevelopixWeb
touchstart و wheel داشته باشه، راحت لگ میزنه. یه ترفند ساده توی جاوااسکریپت کمک میکنه این مشکل خیلی کمتر بشه: استفاده از passive event listener ✅به طور پیشفرض، مرورگر مجبور میشه صبر کنه ببینه توی handler از
event.preventDefault() استفاده میکنی یا نه؛ همین مکث، اسکرول رو کند میکنه. اگه به مرورگر بگی این listener «passive» هست، دیگه صبر نمیکنه و اسکرول رو روان انجام میده. 🚀// همیشه قبل از استفاده، پشتیبانی رو چک کن
const passiveIfSupported = (() => {
let passive = false;
try {
const opts = Object.defineProperty({}, 'passive', {
get() {
passive = { passive: true };
}
});
window.addEventListener('test', null, opts);
} catch (e) {}
return passive;
})();
window.addEventListener('scroll', handleScroll, passiveIfSupported);
function handleScroll(e) {
// اینجا از e.preventDefault() استفاده نشه
}
هر جا فقط میخوای event رو بخونی و قصد
preventDefault() نداری (مثل analytics روی اسکرول یا لمس)، استفاده از گزینه { passive: true } هم UX رو بهتر میکنه هم performance رو. ✨مرجع: MDN - Passive event listeners
🔖 #Web #وب #Frontend #Backend #JavaScript #Performance #Frontend #Scroll #Event_Listener
👤 Developix
💎 Channel: @DevelopixWeb
👍3❤2
Forwarded from Developix Support
This media is not supported in your browser
VIEW IN TELEGRAM
🏆آفرهای جام جهانی ۲۰۲۶ هاستایران فعال شد!
با کمپین «ترکیب برنده سایتت»، زیرساخت سایتت رو برای روزهای پرترافیک آماده کن:
🔥 ۲۵٪ تخفیف روی پلنهای ۳ ماهه هاست اشتراکی ایران
⚡ ۵۰٪ تخفیف روی پلنهای یکماهه سرویس ابری در دیتاسنترهای تهران، مشهد و اهواز
🧠 مشاوره رایگان زیرساخت توسط کارشناسان هاستایران
فرصت استفاده از تخفیفها و ثبت فرم مشاوره محدود است.
📌 برای کپی کدهای تخفیف و ثبتنام در فرم مشاوره، روی لینک زیر کلیک کنید:
📌صفحه فرم مشاوره
📌تلگرام هاستایران
📌بله هاستایران
#هاست_ایران #سرور_ابری_هاست_ایران #هاست_اشتراکی #دیتاسنتر #مشاوره_زیرساخت #جام_جهانی2026
با کمپین «ترکیب برنده سایتت»، زیرساخت سایتت رو برای روزهای پرترافیک آماده کن:
🔥 ۲۵٪ تخفیف روی پلنهای ۳ ماهه هاست اشتراکی ایران
⚡ ۵۰٪ تخفیف روی پلنهای یکماهه سرویس ابری در دیتاسنترهای تهران، مشهد و اهواز
🧠 مشاوره رایگان زیرساخت توسط کارشناسان هاستایران
فرصت استفاده از تخفیفها و ثبت فرم مشاوره محدود است.
📌 برای کپی کدهای تخفیف و ثبتنام در فرم مشاوره، روی لینک زیر کلیک کنید:
📌صفحه فرم مشاوره
📌تلگرام هاستایران
📌بله هاستایران
#هاست_ایران #سرور_ابری_هاست_ایران #هاست_اشتراکی #دیتاسنتر #مشاوره_زیرساخت #جام_جهانی2026
در نمونهکد بالا هندل کردن خطا در Express بهصورت اشتباه انجام شده است؛ Middleware مربوط به خطا باید در انتهای زنجیره Routeها و سایر Middlewareها قرار بگیرد و امضای تابع آن هم باید چهار آرگومان
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb
err، req، res و next را داشته باشد. با رعایت این الگو، خطاهای Async (مثلاً خطاهای Promise در درخواستهای پایگاهداده) بهدرستی لاگ و مدیریت شده و از ارسال پاسخهای ناقص یا Crash شدن ناگهانی سرور در محیط Production جلوگیری میشود.🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb
❤3
در نمونهکد بالا در روش اشتباه، در هر بار اجرا شدن
در روش صحیح با استفاده از یک متغیر سراسری و کشکردن
به این ترتیب، هم مصرف منابع بهشدت کاهش پیدا میکند، هم زمان پاسخگویی API و صفحات server-side بهتر میشود و در عین حال ریسک Memory Leak و اشباع شدن کانکشنهای دیتابیس پایین میآید.
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb
getServerSideProps یک کانکشن جدید به دیتابیس ساخته میشود و هرگز بسته یا دوباره استفاده نمیشود؛ این کار روی سرور واقعی (مثلاً در Next.js زیر بار ترافیک بالا) باعث Connection Exhaustion، افت شدید کارایی و حتی کرش شدن سرویس میشود.در روش صحیح با استفاده از یک متغیر سراسری و کشکردن
MongoClient (یا هر Driver دیگری)، در محیط development جلوی ساخت کانکشنهای تکراری بعد از هر Hot-Reload گرفته شده و در محیط production هم تنها یک بار به دیتابیس متصل میشویم و همه درخواستها از همان کانکشن/Pool استفاده میکنند.به این ترتیب، هم مصرف منابع بهشدت کاهش پیدا میکند، هم زمان پاسخگویی API و صفحات server-side بهتر میشود و در عین حال ریسک Memory Leak و اشباع شدن کانکشنهای دیتابیس پایین میآید.
🔖 #Web #وب #Frontend #Backend
👤 Developix
💎 Channel: @DevelopixWeb
👍2