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

زنجیره‌های میان‌افزار قابل ترکیب (Composable Middleware Chains)

در این بخش، نحوه ایجاد زنجیره‌های میان‌افزار قابل ترکیب (Composable Middleware Chains) را بررسی می‌کنیم. این زنجیره‌ها به ما اجازه می‌دهند تا میان‌افزارها (Middlewares) را به صورت پویا ترکیب کنیم و ترتیب اجرا (Execution Order) را کنترل کنیم.

در این فصل می‌خواهم پکیج justinas/alice را معرفی کنم که به ما در مدیریت زنجیره‌های میان‌افزار/هندلر کمک می‌کند.

شما نیازی به استفاده از این پکیج ندارید، اما دلیلی که من آن را توصیه می‌کنم این است که ایجاد زنجیره‌های میان‌افزار قابل ترکیب و قابل استفاده مجدد را آسان می‌کند - و این می‌تواند با رشد برنامه شما و پیچیده‌تر شدن مسیرها، کمک واقعی باشد. خود پکیج نیز کوچک و سبک است، و کد آن واضح و خوب نوشته شده است.

برای نمایش ویژگی‌های آن در یک مثال، به شما اجازه می‌دهد یک زنجیره هندلر را از این حالت:

return myMiddleware1(myMiddleware2(myMiddleware3(myHandler)))

به این حالت تبدیل کنید، که در یک نگاه درک آن کمی واضح‌تر است:

return alice.New(myMiddleware1, myMiddleware2, myMiddleware3).Then(myHandler)

اما قدرت واقعی در این است که می‌توانید از آن برای ایجاد زنجیره‌های میان‌افزار استفاده کنید که می‌توانند به متغیرها اختصاص داده شوند، به آنها اضافه شود و مجدداً استفاده شوند. برای مثال:

myChain := alice.New(myMiddlewareOne, myMiddlewareTwo)
myOtherChain := myChain.Append(myMiddleware3)
return myOtherChain.Then(myHandler)

اگر همراه ما هستید، لطفاً پکیج justinas/alice را با استفاده از go get نصب کنید:

$ go get github.com/justinas/alice@v1
go: downloading github.com/justinas/alice v1.2.0

و اگر فایل go.mod پروژه خود را باز کنید، باید یک عبارت require جدید مربوطه را مشاهده کنید، به این صورت:

File: go.mod
module snippetbox.alexedwards.net

go 1.23.0

require github.com/go-sql-driver/mysql v1.8.1

require (
    filippo.io/edwards25519 v1.1.0 // indirect
    github.com/justinas/alice v1.2.0 // indirect
)

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

بیایید اکنون این کار را انجام دهیم و فایل routes.go خود را به شرح زیر برای استفاده از پکیج justinas/alice به‌روزرسانی کنیم:

File: cmd/web/routes.go
package main

import (
    "net/http"

    "github.com/justinas/alice" // New import
)

func (app *application) routes() http.Handler {
    mux := http.NewServeMux()

    fileServer := http.FileServer(http.Dir("./ui/static/"))
    mux.Handle("GET /static/", http.StripPrefix("/static", fileServer))
   
    mux.HandleFunc("GET /{$}", app.home)
    mux.HandleFunc("GET /snippet/view/{id}", app.snippetView)
    mux.HandleFunc("GET /snippet/create", app.snippetCreate)
    mux.HandleFunc("POST /snippet/create", app.snippetCreatePost)

    // Create a middleware chain containing our 'standard' middleware
    // which will be used for every request our application receives.
    standard := alice.New(app.recoverPanic, app.logRequest, commonHeaders)

    // Return the 'standard' middleware chain followed by the servemux.
    return standard.Then(mux)
}

اگر می‌خواهید، می‌توانید در این مرحله برنامه را مجدداً راه‌اندازی کنید. باید متوجه شوید که همه چیز به درستی کامپایل می‌شود و برنامه همچنان مانند قبل کار می‌کند. همچنین می‌توانید مجدداً go mod tidy را اجرا کنید تا علامت // indirect از فایل go.mod حذف شود.

واژه‌نامه اصطلاحات فنی

اصطلاح فارسی معادل انگلیسی توضیح
زنجیره‌های میان‌افزار قابل ترکیب Composable Middleware Chains ترکیب پویای میان‌افزارها به صورت زنجیره‌ای
میان‌افزارها Middlewares توابعی که درخواست‌ها را پردازش می‌کنند
ترتیب اجرا Execution Order ترتیب اجرای میان‌افزارها در زنجیره
تابع زنجیره‌ساز Chain Function تابعی که میان‌افزارها را به هم متصل می‌کند
میان‌افزار استاندارد Standard Middleware میان‌افزارهای پایه مورد نیاز برنامه
مسیریاب Router بخشی که درخواست‌ها را به هندلرها هدایت می‌کند
هندلر Handler تابعی که درخواست‌ها را پردازش می‌کند
پردازش درخواست Request Processing عملیات انجام شده روی درخواست‌های دریافتی
مدیریت مسیر Route Handling پردازش درخواست‌ها بر اساس مسیر URL
سرور فایل File Server بخشی که فایل‌های استاتیک را سرو می‌کند