زنجیرههای میدلور ترکیبی
در این فصل میخواهم بسته justinas/alice را معرفی کنم تا به ما در مدیریت زنجیرههای میدلور/handler کمک کند.
شما نیازی به استفاده از این بسته ندارید، اما دلیل توصیه من این است که ایجاد زنجیرههای میدلور ترکیبی و قابل استفاده مجدد را آسان میکند — و این میتواند کمک واقعی باشد وقتی برنامه شما رشد میکند و مسیرهای شما پیچیدهتر میشوند. خود بسته نیز کوچک و سبکوزن است و کد واضح و خوب نوشته شده است.
برای نشان دادن ویژگیهای آن در یک مثال، به شما اجازه میدهد یک زنجیره handler را از این:
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 مربوطه جدید ببینید، به این صورت:
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 بهروزرسانی کنیم:
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 حذف کنید.