DDN ( Daily Dev Notes )
8 subscribers
4 photos
12 links
Download Telegram
Channel photo updated
این یه ابزار خیلی خوب برای استفاده از هوش مصنوعی‌ها هست که می‌تونه تمام ابزارهای محبوب کدنویسی مثل Claude Code، Codex، Cursor، Cline و Copilot رو به ده‌ها ارائه‌دهنده مدل‌های هوش مصنوعی متصل کنه. 🚀

🔹 اسمش 9Router هست؛ یک AI Router متن‌باز که بین ابزار شما و مدل‌های مختلف هوش مصنوعی قرار می‌گیره و به‌صورت هوشمند درخواست‌ها رو مدیریت می‌کنه.

ویژگی‌های جالب:
پشتیبانی از بیش از 40 ارائه‌دهنده و 100+ مدل هوش مصنوعی
سوییچ خودکار بین سرویس‌ها در صورت اتمام سهمیه یا قطعی سرویس
کاهش مصرف توکن تا حدود 20 تا 40 درصد با سیستم RTK
سازگار با Claude Code، Cursor، Codex، Copilot و بسیاری ابزارهای دیگر
متن‌باز و قابل اجرا روی سیستم شخصی یا سرور شما

اگر از چند سرویس AI استفاده می‌کنید و نمی‌خواهید وسط کار به خاطر محدودیت‌ها یا هزینه‌ها متوقف شوید، حتماً این پروژه را بررسی کنید.

⭐️ GitHub: https://github.com/decolua/9router

#AI #OpenSource #Programming #ClaudeCode #Cursor #Codex #Copilot #DeveloperTools

@DDNotes
💡 یک مثال واقعی از کاربرد 9Router

فرض کنید من اشتراک دانشجویی Gemini Pro گوگل رو فعال کردم و به Antigravity دسترسی دارم. طبیعتاً می‌تونم از محیط کدنویسی Antigravity استفاده کنم، اما شخصاً تجربه کار با Claude Code رو بیشتر دوست دارم.

مشکل اینجاست که برای استفاده مستقیم از Claude Code باید یک اشتراک جداگانه تهیه کنم، در حالی که همین حالا بابت اشتراک Gemini هزینه پرداخت شده.

اینجاست که 9Router جذاب می‌شود:

🔹 می‌تونم اکانت Antigravity خودم رو به 9Router وصل کنم و مدل‌های موجود داخلش رو به‌صورت API در اختیار داشته باشم.

🔹 حتی می‌تونم Claude Code رو طوری تنظیم کنم که درخواست‌هاش از طریق 9Router به Antigravity ارسال بشه و از مدل‌ها و سهمیه همون اشتراک استفاده کنه.

یعنی به‌جای اینکه برای هر ابزار AI یک اشتراک جداگانه بخرم، می‌تونم ابزار موردعلاقه‌ام (مثل Claude Code، Cursor یا Codex) رو روی اشتراک‌هایی که از قبل دارم سوار کنم و همه رو از یک نقطه مدیریت کنم.

در واقع 9Router فقط یک Router نیست؛ یک لایه هوشمند بین ابزارهای برنامه‌نویسی و سرویس‌های هوش مصنوعی مختلفه که باعث میشه هزینه کمتر، انعطاف بیشتر و دردسر کمتری داشته باشی. 🚀

@DDNotes
یه پکیج فرم ساز خوب برای لاراول
معمولاً هر پروژه‌ای که جلو میره، یه عالمه فرم جدید لازم پیدا می‌کنه؛ فرم تماس با ما، فرم ثبت‌نام، فرم نظرسنجی، فرم تیکت پشتیبانی، فرم درخواست همکاری و ...
حالا تصور کن به جای اینکه برای هر فرم بری migration، validation، blade و controller جدا بنویسی، یه پنل داشته باشی و همه اینا رو با Drag & Drop بسازی
پکیج Laravel Form Builder دقیقاً برای همین ساخته شده.
چند تا ویژگی خفن:
ساخت فرم با Drag & Drop
بیش از ۲۱ نوع فیلد مختلف
شرطی کردن فیلدها (مثلاً اگه کاربر گزینه خاصی رو انتخاب کرد، فیلد جدید نمایش داده بشه)
آپلود فایل و تصویر
فیلدهای تکرارشونده (Repeater)
خروجی CSV، Excel و PDF
ارسال ایمیل بعد از ثبت فرم
Webhook
API آماده
امکان نمایش فرم با form('slug')
نکته جالبش اینه که فرم‌ها داخل دیتابیس ذخیره میشن و برای اضافه یا تغییر فرم‌ها لازم نیست هر بار کد پروژه رو دستکاری بشه.
برای پروژه‌های SaaS، CRM، پنل مشتریان، سیستم‌های ثبت درخواست و حتی ساخت فرم‌ساز اختصاصی خیلی کاربردیه.
🔗 GitHub:
https://github.com/haider-kamran/laravel-form-builder
#Laravel #PHP #OpenSource #FormBuilder #WebDevelopment
🟢 راه‌اندازی Node.js و Socket.IO روی هاست اشتراکی (cPanel) بخش اول
اگه بخوایم Socket.IO رو روی هاست اشتراکی اجرا کنیم، معمولاً اولین چالش نصب پکیج‌ها و بعد از اون تنظیم مسیرهای Socket.IO هست. توی این آموزش قدم‌به‌قدم می‌بینیم چطور میشه یه اپ Express به همراه Socket.IO رو روی هاست اشتراکی راه‌اندازی کرد.
۱. ساخت اپلیکیشن Node.js
اول از داخل Application Manager یه اپ Node.js جدید می‌سازیم:
آدرس اپ: مثلاً testing
Startup File: app.js
نسخه Node.js: متناسب با نیاز پروژه
بعد از ساخت اپ، پوشه پروژه ایجاد میشه و می‌تونیم فایل‌های مورد نیازمون رو داخلش قرار بدیم.
۲. نصب Dependency ها
بعضی وقت‌ها ممکنه نصب Dependency ها از داخل cPanel امکان‌پذیر نباشه؛ مثلاً زمانی که دسترسی به رجیستری پیش‌فرض npm وجود نداره یا اینترنت بین‌الملل با اختلال مواجه شده.
در این شرایط می‌تونیم داخل پوشه پروژه یک فایل .npmrc ایجاد کنیم و رجیستری مورد نظرمون رو به npm معرفی کنیم.
مثلاً برای استفاده از رجیستری چابکان:
registry=https://mirror2.chabokan.net/npm/

بعد از ذخیره فایل، دوباره از داخل cPanel سعی می‌کنیم Dependency ها رو نصب کنیم.
اگر باز هم cPanel از رجیستری جدید استفاده نکرد، باید نصب رو به صورت دستی انجام بدیم.
اگر به Terminal یا SSH دسترسی داشته باشیم که کار خیلی ساده است:
npm install express socket.io

اما روی بعضی هاست‌های اشتراکی دسترسی SSH وجود نداره.
راه‌حلی که من استفاده کردم این بود که داخل package.json یک اسکریپت برای نصب Dependency ها تعریف کردم:
{
"scripts": {
"npm-install": "npm install"
}
}

بعد از داخل cPanel و بخش Run JS Script اسکریپت npm-install رو اجرا کردم و npm تمام پکیج‌ها رو نصب کرد.
نمونه خروجی موفق:
returncode: 0

stdout:

> node-test@1.0.0 npm-install
> npm install

added 22 packages, and audited 91 packages in 5s

16 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

stderr:

وقتی خروجی مشابه این رو ببینیم یعنی Dependency ها با موفقیت نصب شدن و می‌تونیم سراغ مرحله بعدی یعنی راه‌اندازی Socket.IO بریم.

—————-
@DDNotes
—————-
#NodeJS #SocketIO #WebSocket #cPanel #SharedHosting #ExpressJS #JavaScript #Backend #Realtime #توسعه_وب
🟢 راه‌اندازی Node.js و Socket.IO روی هاست اشتراکی (cPanel) - بخش دوم
توی پست قبلی اپلیکیشن Node.js رو ساختیم و Dependency ها رو نصب کردیم. حالا اگه بخوایم Socket.IO رو روی هاست اشتراکی اجرا کنیم، باید بدونیم که معمولاً Node.js روی cPanel پشت Passenger اجرا میشه و با VPS تفاوت‌هایی داره.
۱. ساخت فایل app.js
اول یه فایل app.js داخل پوشه پروژه می‌سازیم:
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);

اینجا Express و Socket.IO رو مقداردهی اولیه کردیم.
۲. تنظیم Socket.IO
حالا باید Socket.IO رو به سرور HTTP متصل کنیم:
const io = new Server(server, {
cors: {
origin: '*',
},
path: '/testing/socket.io',
});

نکته مهم اینه که مقدار path باید با آدرس اپلیکیشنی که داخل cPanel ساختیم هماهنگ باشه.
فرض کنید اپلیکیشن رو روی آدرس زیر ساخته باشیم:
https://yourdomain.com/testing

در این حالت مسیر Socket.IO باید چیزی شبیه این باشه:
/testing/socket.io

۳. ثبت Route تست
برای اینکه مطمئن بشیم Express درست کار می‌کنه، یه Route تست تعریف می‌کنیم:
app.get('/testing/node-test', (req, res) => {
res.send('Node.js application is working');
});

بعد از Restart کردن اپلیکیشن، با باز کردن این آدرس باید پیام بالا نمایش داده بشه:
https://yourdomain.com/testing/node-test

اگر این صفحه باز شد یعنی Node.js و Express بدون مشکل در حال اجرا هستند.
۴. مدیریت اتصال کاربران
حالا می‌تونیم اولین Event مربوط به Socket.IO رو تعریف کنیم:
io.on('connection', socket => {
console.log('New Client Connected');

socket.emit(
'server-message',
'Socket.IO connection successful'
);
});

هر بار که یک کاربر متصل بشه، این Event اجرا میشه و یک پیام تست برای کلاینت ارسال می‌کنه.
۵. نکته مهم Passenger
روی اکثر هاست‌های اشتراکی نباید از:
server.listen(...)

استفاده کنیم.
Passenger خودش سرور رو مدیریت می‌کنه و معمولاً فقط کافیه در انتهای فایل بنویسیم:
module.exports = server;

بعد از ذخیره فایل، اپلیکیشن رو Restart کنید تا تغییرات اعمال بشن.
در پست بعدی اتصال کلاینت، تست WebSocket و رفع خطای معروف 404 مربوط به Socket.IO رو بررسی می‌کنیم.
—————-
@DDNotes
—————-
#NodeJS #SocketIO #Express #cPanel #SharedHosting #WebSocket #Backend #JavaScript #آموزش_برنامه_نویسی #توسعه_وب
🟢 راه‌اندازی Node.js و Socket.IO روی هاست اشتراکی (cPanel) - بخش سوم
تا اینجا سرور Node.js و Socket.IO رو راه‌اندازی کردیم. حالا اگه بخوایم مطمئن بشیم WebSocket واقعاً کار می‌کنه، باید یه کلاینت تست بسازیم.
۱. اضافه کردن کلاینت Socket.IO
داخل صفحه HTML تست:
<script src="https://cdn.socket.io/4.8.1/socket.io.min.js"></script>

و بعد:
const socket = io({
path: '/testing/socket.io',
});

دقت کنید که مقدار path باید دقیقاً با مقداری که روی سرور تنظیم کردیم یکسان باشه.
۲. دریافت پیام سرور
برای تست اتصال:
socket.on('server-message', message => {
console.log(message);
});

اگر همه چیز درست باشه باید داخل Console مرورگر پیام زیر رو ببینید:
Socket.IO connection successful

۳. خطای معروف 404
یکی از رایج‌ترین خطاهایی که روی هاست اشتراکی دیده میشه اینه:
GET /socket.io/?EIO=4&transport=polling 404

این خطا معمولاً یکی از این دلایل رو داره:
مسیر path روی سرور و کلاینت یکسان نیست.
اپلیکیشن بعد از تغییرات Restart نشده.
درخواست‌ها به جای /testing/socket.io به /socket.io ارسال میشن.
فایل Startup اشتباه انتخاب شده.
۴. بررسی لاگ‌ها
اگر اتصال برقرار نشد، لاگ‌های Node.js داخل cPanel بهترین محل برای پیدا کردن مشکل هستن.
معمولاً خطاهای زیر خیلی کمک می‌کنن:
Cannot find module ...

یا:
EADDRINUSE

یا:
404 Not Found

۵. تست نهایی
اگر:
Route تست Express باز میشه
خطای 404 ندارید
پیام Socket.IO دریافت میشه
یعنی WebSocket با موفقیت روی هاست اشتراکی شما راه‌اندازی شده 🎉
از اینجا به بعد می‌تونید چت آنلاین، نوتیفیکیشن لحظه‌ای، پنل ادمین Real-time و حتی سیستم Broadcast لاراول رو پیاده‌سازی کنید.
—————-
@DDNotes
—————-
#NodeJS #SocketIO #WebSocket #cPanel #SharedHosting #ExpressJS #JavaScript #Backend #Realtime #توسعه_وب
📄 فایل نهایی app.js
اگر همه مراحل پست‌های قبلی رو انجام داده باشید، فایل نهایی می‌تونه چیزی شبیه نمونه زیر باشه:
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');

const app = express();
const server = http.createServer(app);

const io = new Server(server, {
cors: {
origin: '*',
},
path: '/testing/socket.io',
});

app.get('/testing/node-test', (req, res) => {
res.send(`
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Socket.IO Test</title>
</head>
<body>
<h2>Socket.IO Connection Test</h2>

<div id="status">
Connecting...
</div>

<script src="https://cdn.socket.io/4.8.1/socket.io.min.js"></script>

<script>
const socket = io({
path: '/testing/socket.io'
});

socket.on('connect', () => {
document.getElementById('status').innerHTML =
' Connected Successfully';
});

socket.on('server-message', message => {
console.log(message);

document.getElementById('status').innerHTML =
' ' + message;
});

socket.on('disconnect', () => {
document.getElementById('status').innerHTML =
' Disconnected';
});
</script>
</body>
</html>
`);
});

io.on('connection', socket => {
console.log('New Client Connected');

socket.emit(
'server-message',
'Socket.IO connection successful'
);

socket.on('disconnect', () => {
console.log('Client Disconnected');
});
});

module.exports = server;

بعد از ذخیره فایل:
اپلیکیشن رو Restart کنید.
آدرس زیر رو باز کنید:
https://yourdomain.com/testing/node-test

اگر پیام:
 Socket.IO connection successful

نمایش داده شد یعنی هم Express و هم Socket.IO روی هاست اشتراکی شما با موفقیت در حال کار هستند.
💡 فراموش نکنید که مقدار /testing باید با Application URL که داخل cPanel ساخته‌اید یکسان باشد. اگر مثلاً اپلیکیشن را روی /node-app ساخته باشید باید تمام مسیرها را متناسب با آن تغییر دهید.
—————-
@DDNotes
—————-
#NodeJS #SocketIO #Express #cPanel #SharedHosting #WebSocket #JavaScript #Backend #Realtime #توسعه_وب
🚀 میکروسرویس‌ها دقیقاً چی هستن و چرا همه درباره‌شون حرف می‌زنن؟

این روزا هر جا صحبت از معماری نرم‌افزار میشه، یه نفر حتماً اسم Microservice رو میاره! 😅
از نتفلیکس و آمازون گرفته تا اوبر، همه یه جایی از این معماری استفاده می‌کنن.
ولی واقعاً Microservice چیه و چرا اینقدر محبوب شده؟ 🤔
فرض کنیم یه فروشگاه اینترنتی داریم. 👇
توی یه معماری سنتی یا همون Monolith، همه چیز داخل یه پروژه بزرگ قرار می‌گیره:
مدیریت کاربران
محصولات
سفارش‌ها
پرداخت
ارسال پیامک و ایمیل
پنل مدیریت
یعنی همه این بخش‌ها کنار هم توی یه کدبیس قرار دارن.
📦 Monolith = یه ساختمان بزرگ که همه اتاق‌هاش زیر یه سقف هستن
اما توی معماری Microservices داستان فرق می‌کنه.
هر بخش تبدیل میشه به یه سرویس مستقل:
User Service
Product Service
Order Service
Payment Service
Notification Service
هر سرویس کد، دیتابیس، توسعه و استقرار خودش رو داره.
🏘 Microservices = یه شهر کوچیک که از چندین ساختمان مستقل تشکیل شده
خب چرا شرکت‌های بزرگ عاشق Microservice هستن؟
📈 مقیاس‌پذیری بهتر
فرض کنیم یه کمپین تبلیغاتی راه انداختیم و ناگهان تعداد سفارش‌ها ۱۰ برابر شد.
توی Monolith معمولاً باید کل برنامه رو Scale کنیم.
ولی توی Microservices فقط همون Order Service رو Scale می‌کنیم.
یعنی منابع سرور خیلی بهینه‌تر مصرف میشن.
💥 خرابی یک بخش، کل سیستم رو نمی‌خوابونه
فرض کنیم سرویس ارسال ایمیل خراب بشه.
توی خیلی از معماری‌های Monolith ممکنه این خرابی روی بخش‌های دیگه هم اثر بذاره.
اما توی Microservices معمولاً فقط همون سرویس دچار مشکل میشه و بقیه سیستم به کارش ادامه میده.
😎 یعنی یه خرابی کوچیک لزوماً کل کسب‌وکار رو از کار نمیندازه.
👥 تیم‌ها مستقل‌تر کار می‌کنن
حالا فرض کنیم یه شرکت ۵۰ تا برنامه‌نویس داره.
یه تیم روی پرداخت کار می‌کنه.
یه تیم روی سفارش‌ها.
یه تیم روی کاربران.
هر تیم می‌تونه بدون درگیر شدن با بقیه، سرویس خودش رو توسعه بده و نسخه جدید منتشر کنه.
برای همین شرکت‌های بزرگ خیلی راحت‌تر می‌تونن رشد کنن.
ولی یه نکته مهم... ⚠️
Microservice یه عصای جادویی نیست!
درسته که مزایای زیادی داره، اما دردسرهای خودش رو هم داره:
مدیریت چندین سرویس
ارتباط بین سرویس‌ها
مانیتورینگ
لاگینگ
DevOps
مدیریت خطاها
به همین خاطر همیشه هم انتخاب درستی نیست.
توی پست بعدی می‌بینیم چه زمانی باید سراغ Microservice بریم و چه زمانی بهتره اصلاً سمتش نریم! 🔥
—————-
@DDNotes
—————-
#Microservices #SoftwareArchitecture #SystemDesign #Backend #Laravel #DevOps
⚠️ چه زمانی Microservice انتخاب خوبیه و چه زمانی فقط دردسر درست می‌کنه؟
یکی از رایج‌ترین اشتباهات برنامه‌نویس‌ها اینه که فکر می‌کنن:
«هرچی معماری پیچیده‌تر باشه، حرفه‌ای‌تره!»

اما واقعیت اینه که خیلی وقت‌ها ساده‌ترین راه، بهترین راهه. 😅


پروژه‌هایی که بهتره Microservice نباشن
📝 مثال اول: یه وبلاگ ساده
فرض کنیم می‌خوایم یه وبلاگ راه بندازیم.
امکاناتش هم ایناست:
مقاله
دسته‌بندی
کاربران
نظرات
حالا اگه برای این پروژه بیایم:
User Service
Article Service
Comment Service
Category Service
بسازیم، عملاً داریم بی‌دلیل پروژه رو پیچیده می‌کنیم.
چون حالا باید:
چند سرویس رو Deploy کنیم
لاگ‌ها رو مدیریت کنیم
ارتباط سرویس‌ها رو کنترل کنیم
خطاهای شبکه رو هندل کنیم
در حالی که یه Monolith ساده می‌تونه همه این کارها رو خیلی راحت انجام بده.

🛒 مثال دوم: فروشگاه اینترنتی کوچک
فرض کنیم یه فروشگاه اینترنتی داریم که روزی ۵۰ تا سفارش ثبت می‌کنه.
توی همچین شرایطی معمولاً:
توسعه سریع‌تره
هزینه نگهداری کمتره
دیباگ راحت‌تره
تیم کوچیک‌تر هم از پسش برمیاد
پس استفاده از Microservice بیشتر شبیه Over Engineering میشه تا یه تصمیم فنی درست.


نمونه پروژه‌هایی که Microservice توشون می‌درخشه
🚕 اوبر یا اسنپ خودمون
اوبر فقط یه اپ تاکسی نیست!
پشت صحنه ده‌ها سیستم مختلف داره:
مدیریت راننده‌ها
مدیریت مسافرها
پرداخت
قیمت‌گذاری لحظه‌ای
مسیریابی
اعلان‌ها
هر کدوم از این بخش‌ها بار و نیازهای متفاوتی دارن.
اینجاست که Microservices واقعاً ارزش خودش رو نشون میده.

🎬 نتفلیکس
نتفلیکس میلیون‌ها کاربر همزمان داره.
جستجو، پخش ویدیو، پیشنهاد فیلم، مدیریت حساب کاربری و ده‌ها بخش دیگه به صورت مستقل کار می‌کنن.
اگه تیم پیشنهاد فیلم بخواد یه قابلیت جدید منتشر کنه، لازم نیست کل سیستم دوباره Deploy بشه.
این دقیقاً همون جاییه که Microservices می‌درخشه.

یه قانون طلایی که همیشه یادت بمونه 👇
اگه:
تازه پروژه رو شروع کردی
تیم کوچیکی داری
هنوز کاربرهای زیادی نداری
محصولت MVP هست
به احتمال زیاد یه Monolith تمیز و اصولی بهترین انتخابه.
وقتی واقعاً به مشکل مقیاس، تیم‌های متعدد و استقرار مستقل رسیدی، اون موقع می‌تونی به مهاجرت به Microservices فکر کنی.
معمولاً بزرگ‌ترین شرکت‌های دنیا هم اول کار با Monolith شروع کردن و بعداً به سمت Microservices رفتن. 😉


📚 منابع برای مطالعه بیشتر
🔹 مقاله معروف مارتین فاولر:
Microservices - Martin Fowler
🔹 کتاب فوق‌العاده برای شروع:
Building Microservices - Sam Newman

—————-
@DDNotes
—————-
#Microservices #SoftwareArchitecture #SystemDesign #Backend #Laravel #DevOps
👍1
🔌 میکروسرویس‌ها چجوری با هم حرف می‌زنن؟

تا اینجا فهمیدیم که توی معماری Microservices، سیستم از چند سرویس مستقل تشکیل میشه.
اما یه سؤال مهم وجود داره... 🤔
اگه هر سرویس مستقل باشه، پس این سرویس‌ها چجوری با هم ارتباط برقرار می‌کنن؟

فرض کنیم یه کاربر سفارشی ثبت می‌کنه:
Order Service سفارش رو ثبت می‌کنه
Payment Service پرداخت رو انجام میده
Notification Service پیامک ارسال می‌کنه

پس این سرویس‌ها باید یه راهی برای رد و بدل کردن اطلاعات داشته باشن.

به طور کلی دو مدل اصلی ارتباط داریم:
ارتباط مستقیم (Synchronous)
ارتباط غیرمستقیم (Asynchronous)


☎️ ارتباط مستقیم (Synchronous) :
توی این مدل، یه سرویس به سرویس دیگه درخواست می‌فرسته و منتظر جواب می‌مونه.
یه چیزی شبیه تماس تلفنی. 📞
تا طرف مقابل جواب نده، کار ادامه پیدا نمی‌کنه.
برای این مدل ارتباط روش ها و پروتکل های مختلفی وجود داره اما دو تا از اونا که بسیار زیاد استفاده میشن عبارتند از :
RESTAPI, gRPC

🌐 پروتکل REST API
محبوب‌ترین روش ارتباط بین سرویس‌ها همین REST هست.
فرض کنیم Order Service می‌خواد اطلاعات کاربر شماره 123 رو از User Service بگیره.
درخواستی شبیه این ارسال میشه:
GET /users/123

و پاسخ به صورت JSON برمی‌گرده:
{
"id": 123,
"name": "Ali",
"email": "ali@example.com"
}

در واقع REST معمولاً اطلاعات رو به شکل JSON روی HTTP منتقل می‌کنه.
شکل کلی انتقال داده در REST
REST

JSON

{
"id": 123,
"name": "Ali"
}

مزیتش اینه که ساده، خوانا و تقریباً روی همه زبان‌ها و فریمورک‌ها پشتیبانی میشه.
REST رو کی استفاده کنیم؟

ارتباط با فرانت‌اند
APIهای عمومی
پروژه‌هایی که سادگی مهم‌تر از سرعت خام هست

⚡️پروتکل gRPC
حالا فرض کنیم روزانه میلیون‌ها درخواست بین سرویس‌هامون جابجا میشه.
اینجا خیلی از شرکت‌ها به جای REST از gRPC استفاده می‌کنن.
برخلاف REST که JSON جابجا می‌کنه، gRPC از Protocol Buffers (Protobuf) استفاده می‌کنه.
اول ساختار داده رو تعریف می‌کنیم:
message User {
int32 id = 1;
string name = 2;
string email = 3;
}

شکل کلی انتقال داده در gRPC
gRPC

.proto

message User {
int32 id = 1;
string name = 2;
}

بعد هنگام ارسال، این اطلاعات به Binary تبدیل میشن:
0A 03 41 6C 69
12 0F 61 6C 69 ...

😅 طبیعتاً ما معمولاً این بایت‌ها رو مستقیم نمی‌بینیم.
اما به خاطر همین Binary بودن، حجم پیام‌ها کمتر و سرعت انتقال بیشتره.

کی از gRPC استفاده کنیم ؟
ارتباط داخلی بین سرویس‌ها
سیستم‌های پرترافیک
جاهایی که سرعت و Latency خیلی مهمه

(ادامه دارد )
—————-
@DDNotes
—————-
#Microservices #SoftwareArchitecture #SystemDesign #Backend #Laravel #DevOps
⚡️ یه نکته جالب درباره gRPC که کمتر بهش اشاره میشه
توی پست قبل گفتیم gRPC سریع‌تر از REST هست.
اما این سرعت فقط به خاطر Binary بودن Protobufها نیست. 👀
فرض کنیم یه سرویس بخواد این اطلاعات رو دریافت کنه:
اطلاعات کاربر
سبد خرید
سفارش‌ها
آدرس‌های کاربر
در REST معمولاً درخواست‌هایی شبیه این ارسال میشن:
GET /users/123
GET /carts/123
GET /orders/123
GET /addresses/123

یعنی چندین Request جداگانه بین سرویس‌ها رد و بدل میشه.
اما gRPC روی HTTP/2 ساخته شده و یه قابلیت مهم به اسم Multiplexing داره.
یعنی چندین درخواست و پاسخ می‌تونن همزمان روی یه Connection مشترک جابجا بشن.
به شکل ساده:
TCP Connection

├── GetUser()
├── GetCart()
├── GetOrders()
└── GetAddresses()

همه این درخواست‌ها می‌تونن روی همون Connection ارسال بشن. 🚀
البته یه تصور اشتباه رایج هم وجود داره:
REST = برای هر درخواست یک TCP Connection جدید
این جمله همیشه درست نیست.
REST هم می‌تونه Connection رو باز نگه داره و دوباره ازش استفاده کنه.
اما چیزی که gRPC رو متمایز می‌کنه، قابلیت ارسال همزمان چندین Stream روی یک Connection هست.
نتیجه؟
سربار کمتر
Latency کمتر
عملکرد بهتر در ارتباط بین میکروسرویس‌ها
به همین خاطر توی خیلی از سیستم‌های بزرگ، REST برای APIهای عمومی استفاده میشه و gRPC برای ارتباط داخلی بین سرویس‌ها. 😎
—————-
@DDNotes
—————-
#Microservices #gRPC #RESTAPI #HTTP2 #Backend #SystemDesign
DDN ( Daily Dev Notes )
🔌 میکروسرویس‌ها چجوری با هم حرف می‌زنن؟ تا اینجا فهمیدیم که توی معماری Microservices، سیستم از چند سرویس مستقل تشکیل میشه. اما یه سؤال مهم وجود داره... 🤔 اگه هر سرویس مستقل باشه، پس این سرویس‌ها چجوری با هم ارتباط برقرار می‌کنن؟ فرض کنیم یه کاربر سفارشی…
📬 ارتباط غیرمستقیم (Asynchronous)
حالا بریم سراغ مدل دوم.
فرض کنیم Order Service یه سفارش جدید ثبت کرده.
به جای اینکه مستقیم Notification Service رو صدا بزنه، یه پیام داخل یه صف قرار میده.
بعد Notification Service هر وقت آماده بود، اون پیام رو برمی‌داره و پردازش می‌کنه.
📦 درست مثل اینکه یه نامه بندازی داخل صندوق پست.
لازم نیست گیرنده همون لحظه حضور داشته باشه.

توی ادامه ی پست در مورد معروف ترین ابزار هایی که این مدل ارتباط رو برامون برقرار میکنن صحبت میکنیم
🐰 RabbitMQ و 📨 Apache Kafka
برای این مدل معمولاً از Message Brokerها استفاده می‌کنیم.
معروف‌ترین‌ها:
RabbitMQ
Apache Kafka
کارشون اینه که پیام‌ها رو بین سرویس‌ها جابجا کنن.
برای استفاده از این مسیج بروکر ها باید معماری Event-Driven داشته باشیم .

🎯 حالا معماری Event-Driven یعنی چی؟
قبل از هر جیز باید اشاره کنم که توی این مثال همه سرویس ها دارن به message broker گوش میدن و بهش متصلن.
فرض کنیم یه سفارش جدید ثبت شده.
Order Service یه Event منتشر می‌کنه:
{
"event": "OrderCreated",
"order_id": 987,
"user_id": 123,
"total_price": 250
}

شکل کلی انتقال داده در Event Driven
Kafka / RabbitMQ

Event

{
"event": "OrderCreated",
"order_id": 987
}

بعد هر سرویسی که به این رویداد علاقه‌مند باشه می‌تونه اون رو دریافت کنه:
Payment Service
Notification Service
Analytics Service
Loyalty Service
جالب اینجاست که Order Service حتی خبر نداره چه سرویس‌هایی دارن این Event رو مصرف می‌کنن. 😎

🔥 تفاوت اصلی رو با یه مثال ببینیم
فرض کنیم سفارشی ثبت شده و می‌خوایم پیامک ارسال کنیم.
در REST
POST /notifications/send

سرویس Order Service باید مستقیم با Notification Service صحبت کنه.
پس Notification Service باید همون لحظه آنلاین باشه.
در gRPC
rpc SendNotification(NotificationRequest)
returns (NotificationResponse);

باز هم Notification Service باید در دسترس باشه.
در Kafka یا RabbitMQ
{
"event": "OrderCreated",
"order_id": 987
}

سرویس Order Service فقط Event رو داخل Broker قرار میده و کارش تموم میشه.
هر زمان Notification Service آنلاین شد، پیام رو دریافت و پردازش می‌کنه
.
💥 چرا Event-Driven جلوی خرابی زنجیره‌ای رو می‌گیره؟
فرض کنیم Notification Service از کار افتاده.
در ارتباط مستقیم، ممکنه درخواست‌ها یکی یکی Fail بشن و کم‌کم مشکل به سرویس‌های دیگه هم منتقل بشه.
اما توی معماری Event-Driven، پیام‌ها داخل Kafka یا RabbitMQ ذخیره میشن و بعد از برگشتن سرویس پردازش میشن.
یعنی خرابی یه سرویس، لزوماً بقیه سیستم رو زمین نمی‌زنه. 🚀

🧠 پس کدوم بهتره؟
مثل اکثر سؤال‌های معماری نرم‌افزار، جواب اینه:
بستگی داره! 😄

معمولاً:
🔹 REST → برای APIهای عمومی
🔹 gRPC → برای ارتباط سریع بین سرویس‌ها
🔹 Kafka / RabbitMQ → برای Eventها و پردازش‌های غیرهمزمان
و نکته جالب اینه که اکثر سیستم‌های بزرگ از هر سه روش در کنار هم استفاده می‌کنن.
📚 منابع
🔹 برای درک عمیق‌تر Messaging، Eventها و سیستم‌های توزیع‌شده:
Designing Data-Intensive Applications - Martin Kleppmann
🔹 برای یادگیری Kafka:
Confluent Blog
—————-
@DDNotes
—————-
#Microservices #Kafka #RabbitMQ #gRPC #RESTAPI #SystemDesign #SoftwareArchitecture #Backend #DevOps
#Education_Prompt
🤖 اینکه Claude توکن کمتری مصرف کنه و دیرتر به محدودیت برسه...

1⃣وقتی با Claude (یا هر مدل زبانی دیگه‌ای) صحبت می‌کنی، صحبت‌ها تبدیل به یه سری قطعه‌ی کوچیک به اسم توکن میشن.
2⃣هر توکن تقریباً معادل ۳-۴ حرف انگلیسیه یا یه کلمه‌ی کوتاه.
وقتی فارسی صحبت می‌کنید معمولاً توکن بیشتری مصرف می‌کنه چون مدل برای فارسی به اندازه‌ی انگلیسی بهینه نیست.
3⃣مقدار استفاده‌ای که میشه از Claude داشت براساسِ توکن‌هایی که شما می‌فرستید (input)، هم توکن‌هایی که Claude جواب میده (output) هست.
🔢 همه‌ی چیزی که Claude توی یه مکالمه می‌بینه:
پیام‌های قبلی
جواب‌های قبلی Claude
فایل‌هایی که آپلود کردید
دستورالعمل‌های سیستم
نکته‌ی کلیدی: هر بار که پیام جدید می‌فرستید، Claude کل مکالمه رو از اول دوباره می‌خونه.
یعنی اگه ۲۰ پیام رد و بدل کردید، پیام ۲۱‌ ام توکنِ پردازش هر ۲۱ پیام رو داره، نه فقط آخری.
این یعنی مکالمه‌ی طولانی = توکن خیلی بیشتر برای هر پیام جدید.
چیا باعث میشه توکن زیاد مصرف بشه؟
۱. مکالمه‌ی طولانی بدون شروع تازه: هرچی چت طولانی‌تر بشه، هر پیام جدید توکن بیشتری مصرف می‌کنه.
۲. فایل‌های بزرگ آپلود کردن
۳. سوال‌های مبهم یا کلی : وقتی سوال نامشخص یا کلی می‌پرسید، Claude مجبوره طولانی جواب بده یا کلی فایل بخونه.
خواستن خروجی طولانی چیکار کنیم؟

۱. برای هر کار جدید، چت جدید باز کنید. مثلا نیاید توی همون چتی که داشتید گزارشکار می‌نوشتید، یهو از الکترومغناطیس سوال بپرسید.
چت جدید = context خالی = مصرف کم.
۲. سوال رو مشخص و با جزئیات بپرسید.
۳. فایل‌های غیرضروری آپلود نکنید.
۴. اگه چت خیلی طولانی شد، خلاصه‌اش رو کپی کنید و توی چت جدید بذارید.
۵. از مدل مناسب استفاده کنید.
🏷 مستر پرامپت | Mr Prompt
🔗Telgram | Bale
Forwarded from یک برنامه نویس تنبل (Arshia)
Laravel Migration Cheat Sheet
بهترین روش استفاده از enum و cast در Laravel

@TheRaymondDev
Forwarded from laravel-news
docker-compose.yml:


services:
laravel:
container_name: laravel
image: my-image-app
ports:
- "443:443"

mysql:
container_name: mysql
image: mysql:8.0
expose:
- 3306
volumes:
- mysql:/var/lib/mysql
Forwarded from Golden Code (Ali 🇨🇴)
بیشتر ما می‌نویسیم:
$user = User::where('email', $email)->firstOrFail();

اما اگه انتظار دارین دقیقاً یک رکورد وجود داشته باشه، "sole()" میتونه انتخب بهتری باشه:
$user = User::where('email', $email)->sole();

تفاوتشون؟

شرایطی رو تصور کنید که به اشتباه دو رکورد با ایمیل یکسان داریم.
اگه از sole استفاده کنیم بهمون خطا میده چون انتظار داره فقط یک رکورد برگرده،

اما firstOrFail میره و اولین رکورد رو برامون میاره

"firstOrFail()"

- اگه رکوردی نباشد : خطا
- اگر چند رکورد باشن : اولین رکورد رو برمی‌گردونه

"sole()"

- اگه رکوردی نباشه :خطا
- اگر چند رکورد باشد : خطا

این تفاوت باعث میشه اگر داده‌های تکراری به اشتباه وارد دیتابیس بشن، خیلی زودتر متوجه مشکل بشیم.

#Laravel #Laravel_tip #لاراول

@GoldenCodeir 🔥
(به‌منبع و مثالش دقت کنید 👇🏾)
https://x.com/i/status/2062587421121028409
👩‍💻 چند نفر هنوز این اشتباه رو توی Validation لاراول انجام میدن؟ 👀

بیشتر مواقع برای بررسی وجود یک رکورد، این قانون رو می‌نویسیم:


Rule::exists('users', 'id')

اما یک مشکل وجود دارد...

اگر از Soft Delete استفاده می‌کنید، این Rule رکوردهای حذف‌شده را هم معتبر می‌داند. 😐

راه‌حل ساده است:


Rule::exists('users', 'id')->whereNull('deleted_at');


به این شکل فقط رکوردهای فعال اعتبارسنجی می‌شوند و دیگر شناسه کاربران Soft Deleted پذیرفته نخواهد شد.

این نکته کوچک می‌تواند از باگ‌های عجیبی جلوگیری کند؛ مخصوصاً در APIهایی که روی امنیت و صحت داده حساس هستند.
مدیریت
کنید؟

#Laravel #لاراول

📱 @MilwadKhosravi
Please open Telegram to view this post
VIEW IN TELEGRAM
🚀 یه نکته‌ی باحال توی لاراول که شاید خیلیا هنوز ازش استفاده نمی‌کنن!

اگه هنوز اینجوری می‌نویسی:
User::whereHas('posts', function ($query) {
$query->where('status', 'published');
})->with(['posts' => function ($query) {
$query->where('status', 'published');
}])->get();

😅 یه مشکل کوچیک داری...

همون شرط status = published رو دوبار نوشتی؛
یه بار برای whereHas() و یه بار هم برای with().

لاراول برای این قضیه یه متد تمیزتر داره:
User::withWhereHas('posts', function ($query) {
$query->where('status', 'published');
})->get();

🎯 با withWhereHas() هم رکوردهای اصلی فیلتر میشن، هم همون Relation با همون شرط Eager Load میشه.

### چرا بهتره؟ 🤔

کد کمتر
خوانایی بیشتر
حذف کدهای تکراری (DRY)
نگهداری و تغییرات راحت‌تر

💡 این قابلیت از اون ویژگی‌های کوچیک لاراوله که شاید زیاد به چشم نیاد، ولی وقتی توی پروژه‌های بزرگ ازش استفاده کنی، حسابی کدت تمیزتر و قابل نگهداری‌تر میشه.

🔥 شما قبلاً از withWhereHas() استفاده کردین یا هنوز همون ترکیب whereHas() + with() رو می‌نویسین؟

💬 نظرتون رو توی کامنت‌ها بنویسید.
‐------------
@DDNotes
-------------
#Laravel #PHP #Eloquent #LaravelTips #CleanCode #Backend #Programming
👍1