<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"><channel><title>نوشته های amir bahrami</title><link>https://virgool.ir/feed/@amirbahrami.work</link><description></description><language>fa</language><pubDate>2026-11-11 02:01:12</pubDate><image><url>https://files.virgool.ir/upload/users/751972/avatar/QI0hHF.jpg</url><title>amir bahrami</title><link>https://virgool.ir/@amirbahrami.work</link></image><item><title>اضافه کردن gRPC به Laravel بدون بازنویسی کل برنامه</title><link>https://virgool.ir/@amirbahrami.work/اضافه-کردن-grpc-به-laravel-بدون-بازنویسی-کل-برنامه-ctx0d5ttj0z6</link><description>وقتی تیم ما تصمیم گرفت از gRPC در معماری میکروسرویسی خود استفاده کند، با یک چالش جالب روبه‌رو شد.راه‌حل‌های متداول این بود که یا از پیاده‌سازی رسمی gRPC برای PHP استفاده کنیم، یا کل پروژه Laravel را به یک Runtime دائمی مانند Octane، RoadRunner یا OpenSwoole منتقل کنیم.اما هیچ‌کدام از این گزینه‌ها دقیقاً با نیازهای ما هم‌خوانی نداشت.هدف ما تغییر مدل اجرای Laravel نبود؛ فقط می‌خواستیم سرویس‌های مختلف بتوانند از طریق gRPC با اپلیکیشن ارتباط برقرار کنند، بدون اینکه مجبور شویم ساختار فعلی برنامه را بازنویسی کنیم.در این مقاله می‌خواهم تجربه، تصمیم‌های معماری و Trade-offهایی را که در این مسیر داشتیم به اشتراک بگذارم.مسئله چه بود؟اپلیکیشن Laravel ما از قبل همه چیز را در اختیار داشت:ControllerهاMiddlewareهاسیستم احراز هویتValidationهاRoutingهااگر قرار بود برای gRPC دوباره سرویس‌های جداگانه بنویسیم، عملاً باید همان Business Logic را در دو نقطه مختلف نگهداری می‌کردیم؛ یک بار برای HTTP و یک بار برای gRPC.برای همین به جای بازنویسی منطق برنامه، سؤال دیگری مطرح کردیم:آیا می‌توان یک درخواست gRPC را به شکلی تبدیل کرد که Laravel آن را دقیقاً مانند یک درخواست HTTP معمولی پردازش کند؟راه‌حلی که انتخاب کردیمایده اصلی بسیار ساده بود.به جای اینکه منطق برنامه را داخل Handlerهای gRPC بنویسیم، یک لایه واسط ایجاد کردیم که درخواست gRPC را به یک Illuminate\Http\Request تبدیل می‌کند.در نهایت مسیر اجرای درخواست به این شکل شد:مسیر اجرای درخواستاز دید Laravel هیچ تفاوتی وجود ندارد.برنامه همچنان یک Request معمولی دریافت می‌کند و تمام بخش‌های قبلی مانند Middleware، Validation، Authentication و Controllerها بدون هیچ تغییری اجرا می‌شوند.چرا OpenSwoole؟ممکن است با دیدن این پروژه تصور کنید دلیل انتخاب OpenSwoole فقط gRPC بوده است.اما واقعیت این نیست.در این پروژه علاوه بر gRPC به قابلیت‌های دیگری نیز احتیاج داشتیم:ابزای برای WebSocket Processهای دائمیTaskهای پس‌زمینهCoroutineهابه همین دلیل ترجیح دادیم به جای استفاده از Runtimeهای مختلف، همه این قابلیت‌ها را روی یک زیرساخت واحد پیاده‌سازی کنیم.در واقع OpenSwoole برای ما فقط یک gRPC Server نبود؛ بلکه Runtime اصلی اجرای سرویس‌ها محسوب می‌شد.یک تصمیم آگاهانهشاید عجیب‌ترین بخش این پروژه همین قسمت باشد.با اینکه سرور روی OpenSwoole اجرا می‌شود، ما عمداً از قابلیت نگهداری دائمی وضعیت برنامه استفاده نکردیم.در هر درخواست gRPC، اپلیکیشن Laravel دوباره Boot می‌شود و درخواست مانند یک درخواست معمولی وارد HTTP Kernel می‌شود.این تصمیم باعث شد بخشی از مزیت Performance مربوط به Long-running Application را از دست بدهیم، اما در مقابل مزایای مهمی به دست آوردیم:ایزوله بودن کامل هر درخواستحذف مشکلات مربوط به Shared Stateکاهش ریسک مهاجرتعدم نیاز به تغییر ساختار پروژه فعلیهدف ما افزایش حداکثری سرعت نبود؛ هدف، اضافه کردن gRPC با کمترین تغییر ممکن در معماری موجود بود.آیا استفاده از Extension رسمی gRPC بهتر نبود؟پاسخ کوتاه این است:بله، امکان پیاده‌سازی همین ایده با Extension رسمی gRPC نیز وجود داشت.در واقع لایه‌ای که درخواست gRPC را به Request لاراول تبدیل می‌کند، وابسته به OpenSwoole نیست.اما از آنجایی که پروژه علاوه بر gRPC به WebSocket، Process و Task نیز احتیاج داشت، OpenSwoole انتخاب منطقی‌تری برای زیرساخت پروژه بود.مهم‌ترین چیزی که یاد گرفتمبزرگ‌ترین چالش این پروژه، پیاده‌سازی gRPC نبود.چالش اصلی این بود که چگونه یک پروتکل جدید را وارد سیستم کنیم، بدون اینکه مجبور شویم کل برنامه را بازنویسی کنیم.در نهایت با ایجاد یک لایه سازگارکننده (Compatibility Layer)، توانستیم درخواست‌های gRPC را به درخواست‌های استاندارد Laravel تبدیل کنیم و از تمام امکانات موجود برنامه بدون هیچ تغییر اساسی استفاده کنیم.جمع‌بندیدر حال حاضر این پکیج به دلیل محدودیت‌های سازمانی امکان انتشار عمومی ندارد؛ به همین دلیل تصمیم گرفتم به جای انتشار کد، تجربه و تصمیم‌های معماری آن را به اشتراک بگذارم.به اعتقاد من، انتخاب یک فناوری همیشه به معنای انتخاب «بهترین ابزار» نیست.بلکه به معنای انتخاب ابزاری است که بهترین تناسب را با نیازها و محدودیت‌های پروژه داشته باشد.در پروژه ما، OpenSwoole فقط نقش یک سرور gRPC را نداشت؛ بلکه بستری واحد برای اجرای gRPC، WebSocket، Processها و Taskهای پس‌زمینه فراهم کرد، در حالی که Laravel همچنان همان چرخه اجرای همیشگی خود را حفظ کرد.ساختار پکیجمن این مقاله را به دو زبان فارسی و انگلیسی منتشر کرده‌ام. اگر مایل باشید، نسخه انگلیسی آن را نیز می‌توانید در Medium مطالعه کنید:🔗 Medium: https://medium.com/@amirbahrami.work/introducing-grpc-to-laravel-without-rewriting-the-application-03d9e13d0960</description><category>amir bahrami</category><author>amir bahrami</author><pubDate>Wed, 15 Jul 2026 16:45:23 +0330</pubDate></item></channel></rss>