Let's Go میدل‌ور › نحوه کار میدل‌ور
قبلی · فهرست · بعدی
فصل ۶.۱.

نحوه کار میدل‌ور

قبلاً در کتاب چیزی گفتم که می‌خواهم در این فصل گسترش دهم:

“می‌توانید یک برنامه وب Go را به عنوان زنجیره‌ای از متدهای ServeHTTP() که یکی پس از دیگری فراخوانی می‌شوند، تصور کنید.”

در حال حاضر، در برنامه ما، هنگامی که سرور ما یک درخواست HTTP جدید دریافت می‌کند، متد ServeHTTP() servemux را فراخوانی می‌کند. این متد handler مربوطه را بر اساس متد درخواست و مسیر URL جستجو می‌کند و به نوبه خود متد ServeHTTP() آن handler را فراخوانی می‌کند.

ایده اصلی میدل‌ور، درج یک handler دیگر در این زنجیره است. handler میدل‌ور برخی منطق را اجرا می‌کند، مانند ثبت یک درخواست، و سپس متد ServeHTTP() handler بعدی در زنجیره را فراخوانی می‌کند.

در واقع، ما در حال حاضر در برنامه خود از برخی میدل‌ور استفاده می‌کنیم — تابع http.StripPrefix() از سرو کردن فایل‌های استاتیک، که یک پیشوند خاص را از مسیر URL درخواست حذف می‌کند قبل از ارسال درخواست به سرور فایل.

الگو

الگوی استاندارد برای ایجاد میدل‌ور خود به این صورت است:

func myMiddleware(next http.Handler) http.Handler {
    fn := func(w http.ResponseWriter, r *http.Request) {
        // TODO: Execute our middleware logic here...
        next.ServeHTTP(w, r)
    }

    return http.HandlerFunc(fn)
}

خود کد بسیار مختصر است، اما چیزهای زیادی در آن وجود دارد که باید درک کنید.

اگر این گیج‌کننده به نظر می‌رسد، می‌توانید آن را ساده‌تر تصور کنید: myMiddleware() تابعی است که handler بعدی (next handler) در یک زنجیره را به عنوان پارامتر می‌پذیرد. این تابع یک handler برمی‌گرداند که برخی منطق را اجرا می‌کند و سپس handler بعدی را فراخوانی می‌کند.

ساده‌سازی میدل‌ور

یک تغییر در این الگو، استفاده از یک تابع ناشناس در داخل میدل‌ور myMiddleware() است، به این صورت:

func myMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // TODO: Execute our middleware logic here...
        next.ServeHTTP(w, r)
    })
}

این الگو در دنیای واقعی بسیار رایج است و احتمالاً بیشترین چیزی است که اگر کد منبع برنامه‌های دیگر یا بسته‌های شخص ثالث را می‌خوانید، خواهید دید.

موقعیت‌یابی میدل‌ور

مهم است توضیح دهیم که موقعیت میدل‌ور در زنجیره handlerها بر رفتار برنامه شما تأثیر می‌گذارد.

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

myMiddleware → servemux → application handler

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

به طور جایگزین، می‌توانید میدل‌ور را بعد از servemux در زنجیره قرار دهید — با پوشاندن یک handler برنامه خاص. این باعث می‌شود میدل‌ور شما فقط برای یک مسیر خاص اجرا شود.

servemux → myMiddleware → application handler

یک مثال از این مورد، چیزی مانند میدل‌ور احراز هویت است که ممکن است فقط بخواهید روی مسیرهای خاص اجرا شود.

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