ممکن است شنیده باشید برخی افراد در حوزه تکنولوژی از اصطلاحی به نام میان افزار (middleware) در زمینههای مختلف استفاده میکنند و شاید این سؤال برایتان پیش آمده که میان افزار دقیقاً چیست و این افراد در مورد چه چیزی صحبت میکنند؟ برای اینکه با این مفهوم بیشتر آشنا شوید، توصیه میکنیم در ادامه این مقاله از دیجی رو با ما همراه باشید.
میان افزار معانی متعددی دارد
میان افزار (Middleware) یک اصطلاح جامع است که افراد از آن برای اشاره به موارد مختلفی استفاده میکنند. در معنای وسیعترین و عام، میتوان میان افزار را به عنوان “برنامههایی که بین برنامههای دیگر اجرا میشوند” در نظر گرفت. به عبارت دیگر، هر نرم افزاری که برای ارائه ورودی و پردازش خروجی خود به کدهای جداگانهای وابسته است، یک میان افزار تلقی میشود.
برخی از میان افزارها، با داشتن پروتکلها و قالبهای داده مشخص برای استفاده توسط سایر کدها، به عنوان یک برنامه کامل که دادهها را از یک حالت به حالت دیگر تبدیل میکنند، تلقی میشوند. اما میان افزار میتواند یک تابع بسیار ساده نیز باشد که به مجموعهای از توابع دیگر که توسط یک فریمورک اجرا میشوند، متصل شده است.
مانند بسیاری از نرم افزارها، میان افزارها نیز از مفهوم ماژولاریته (تقسیم یک فرایند پیچیده به قطعات کوچکتر و قابل مدیریت) استفاده میکنند.
میان افزار چگونه کار میکند؟
قدرت میان افزار معمولاً به پروتکلها و رفتارهای تعریف شده عمومی آن بستگی دارد. پروتکلهای سختگیرانه یا Strict Protocols مجموعهای از قوانین و استانداردهای بسیار دقیق و مشخص هستند که باید توسط سیستمها و برنامهها برای ارتباط و تبادل اطلاعات با یکدیگر رعایت شوند. این پروتکلها به برنامهنویسان اجازه میدهند نرمافزاری بنویسند که برای عملکرد، با یکسری استانداردها همخوانی داشته باشد.
یک سرور برنامه تحت وب به عنوان میان افزار عمل میکند تا تجربه کاربری نهایی یک وبسایت را به منطق و مدل دادهای که برنامه و پایگاه داده پشتی تعیین میکند، متصل کند. از آنجا که این سرور به سیستمی که با آن ارتباط برقرار میکنند به طور کامل وابسته نیست، شما میتوانید [دست کم در تئوری] یک سرور برنامه را با یک سرور مناسب دیگر جایگزین کنید بدون اینکه نیاز به بازنویسی کدهای برنامه یا ساخت مجدد پایگاه داده داشته باشید.
اجزای میان افزار اغلب از فناوریهایی مانند JSON ،REST ،XML و SOAP استفاده میکنند. این فناوریها همگی بالغ، محبوب و مبتنی بر متن هستند و همین ویژگیها جایگزین کردن یا تغییر ترتیب اجزا را بسیار آسانتر میکند. قالب مبتنی بر متن آنها و مجموعه ابزارهای گسترده نیز باعث آسانتر و قابل اطمینانتر شدن فرایند اشکالزدایی یا دیباگ (Debugging) میشود.
انواع مختلف میان افزار
از آنجایی که این اصطلاح بسیار گسترده است، مثالها و کاربردهای متعددی برای میان افزار وجود دارد. برخی از متداولترین آنها عبارتند از:
- واسطههای پیام (Message brokers) که یک ساختار به ارتباطات بین فرایندی اضافه میکنند.
- سرورهای برنامه تحت وب و فریمورکهای تحت وب
- موتورهای بازیسازی که رفتاری پیش فرض را ارائه میکنند و میتوانید از آن استفاده کرده، آن را توسعه دهید یا جایگزین کنید.
- پلتفرمهای استریم رویداد مانند آپاچی کافکا (Apache Kafka)
استفاده از میان افزار در توسعه نرم افزار
یکی از ملموسترین کاربردهای میان افزار از طریق فریمورکهای تحت وب است. اکثر فریمورکها یک محیط کلی را فراهم میکنند که میتوانید آن را بر اساس نیازهای خود سفارشیسازی کرده و توسعه دهید. این مدل اغلب شامل عبور دادن درخواستهای HTTP از طریق مجموعهای از توابع ساخته شده داخلی و سفارشی، با ترتیبی مشخص، و بازگرداندن پاسخ HTTP در انتهای کار است.
فریمورک Express.js از این مدل برای پشتیبانی از سفارشیسازی استفاده میکند. مثال زیر یک تابع میان افزار نوشته شده به زبان جاوا اسکریپت است:
app.use('/user/:id', (req, res, next) => {
console.log('Request Type:', req.method)
next()
})
روند کاری این تابع بسیار ساده است:
- URLهای خاصی را که با “/user/” شروع شده و در ادامه یک شناسه یا id دارند را پردازش میکند.
- نوع درخواست مثل GET ،POST و غیره را ثبت میکند.
- تابع next را که از قبل آماده شده، فراخوانی میزند تا پردازش زنجیرهٔ توابع میان افزار ادامه یابد.
فراخوانی تابع next گام مهمی در فرایند میان افزار است و نشان میدهد این رویکرد چقدر انعطافپذیر است. تا زمانی که هر تابع میان افزار به طور مستقل عمل کند، میتوانید آنها را جایگزین کرده و رفتار کل زنجیره را به راحتی تغییر دهید.
فریمورک لاراول (Laravel) نیز تنظیمات میان افزاری تقریباً مشابهی دارد. به نحوه تعریف صریح فضای نام برای این کلاس به عنوان “میان افزار” توجه کنید.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class EnsureTokenIsValid
{
/**
* Handle an incoming request.
*/
public function handle(Request $request, Closure $next): Response
{
if ($request->input('token') !== 'my-secret-token') {
return redirect('home');
}
return $next($request);
}
}
در اینجا هم، نقش این کلاس خاص بسیار واضح است: تنها کاری که انجام میدهد بررسی درخواست است تا ببیند که آیا حاوی یک توکن هست یا نه. در این حالت، تابع میان افزار میتواند زنجیره را بشکند، از فراخوانی تابع بعدی خودداری کرده و به جای آن، یک تغییر مسیر (ریدایرکت) ارسال کند. تابع ریدایرکت یک شیء پاسخ مناسب (Response) بازمیگرداند که تابع میان افزار باید آن را به عنوان بخشی از قرارداد امضای خود بازگرداند.
توضیح: در برنامهنویسی، “signature contract” یا “قرارداد امضا” به تعریف و انتظاراتی گفته میشود که از یک تابع یا متد خاص در یک کلاس یا واحد برنامهنویسی وجود دارد. در مورد میان افزارها (middleware) در فریمورکهای تحت وب، به مجموعهای از قوانین و همچنین ساختار خروجی گفته میشود که تابع میان افزار باید به آنها پایبند باشد.
مثال آخری که ارائه میکنیم، نشان میدهد که چگونه Django، به عنوان یک فریمورک وب مبتنی بر پایتون، میان افزارها را مدیریت میکند. Django از واژه “پلاگین” برای توصیف معماری میان افزار خود استفاده میکند، که مشابه با دیگر واژههای مرتبطی است که ممکن است بشنوید مانند “hook” یا “callback”. در اصل، این یکی دیگر از مواردی است که در آن شاهد هستیم چگونه تنظیمات یک میان افزار موجب انعطافپذیری آن طی یک روند ساختاریافته میشود.
def simple_middleware(get_response):
# One-time configuration and initialization.
def middleware(request):
# Code to be executed for each request before
# the view (and later middleware) are called.
response = get_response(request)
# Code to be executed for each request/response after
# the view is called.
return response
return middleware
در ادامه، شما با یک آرایه ساده میتوانید کنترل کنید که کدام میان افزارها و با چه ترتیبی باید اجرا شوند:
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
Django رفتار پیشفرضی مانند کلاس CommonMiddleware را نشان میدهد که اکثر برنامهها از آن بهرهمند خواهند شد؛ این کلاس دسترسی به برخی از عوامل کاربری بد را مسدود کرده و عملیات نرمالسازی URLها را انجام میدهد. بسیار مرسوم و متداول است که میان افزارهای حیاتی و متمرکز بر امنیت، در ابتدای پایپلاین اجرا شوند، اما این انعطافپذیری به شما امکان میدهد ترتیب را بسته به نیازهای برنامه خود تغییر دهید.
چرا میان افزار مفید است؟
میان افزار باعث میشود تا بتوان برنامههایی را که اساساً برای اتصال به یکدیگر طراحی نشدهاند، به آسانی متصل نمود. همچنین، این امکان را فراهم میآورد تا آنها را همراه با پروتکلهای قوی و ساختارمندی که به واسطه آنها میتوانند با هم ارتباط برقرار کنند، با یکدیگر ادغام کرد.
به همین دلیل، میان افزار فواید مهمی را به همراه دارد، از جمله:
- فرایند توسعه برنامهها را تسهیل کرده و زمان عرضه به بازار را کاهش میدهد.
- اتصالات مؤثرتری را فراهم میکند.
- اعمال تغییرات را سادهتر و سریعتر میکند.
- ابزارهای کاری را در دسترستر میکند.
در نهایت، میان افزار نوعی از مدولاریته (تقسیم یک سیستم پیچیده به بخشهای مجزا) است. مفهومی که در تمامی فرمهای برنامهنویسی، از بالاترین سطح گرفته تا پایینترین آن، بسیار مفید است. به طور خلاصه، کارکردهای اصلی میان افزار در برنامهنویسی عبارتند از:
- تسهیل ارتباط: میانافزار امکان ارتباط و انتقال دادهها بین برنامههای کاربردی مختلف را فراهم میکند.
- ایجاد استاندارد: ارائه یک روش معیاری برای انجام کارهای معمول مثل احراز هویت، رمزنگاری و مدیریت دسترسی.
- واسط کاربری: فراهم آوردن یک واسط کاربری مشترک برای مدیریت تنظیمات و پیکربندیهای مختلف بین برنامهها و سرورها.
- مدیریت درخواستها و پاسخها: در یک برنامه تحت وب، میان افزار میتواند درخواستهای HTTP را دریافت و پردازش کند، تا اقداماتی مانند اصلاح هدرها، اعتبارسنجی دادهها، یا گزارش و حسابرسی انجام شود قبل از اینکه به کنترلر روت مربوطه فرستاده شود.
- امنیت: میان افزار میتواند سطوح مختلفی از امنیت را ایجاد کرده و به مدیریت تهدیدات و حملات احتمالی کمک کند.
- افزایش تجدیدپذیری و مقیاسپذیری: به دلیل تفکیک وظایف معین در میان افزار، میتوان بخشهایی از برنامهها را بدون اثر بر دیگر قسمتها، تغییر داد یا بهینه ساخت.