نحوه ساخت یک میانافزار مؤثر
اجزای تشکیلدهنده
میانافزار معمولاً از دو بخش تشکیل شده است:
-
بخش اول یک بار اجرا میشود، زمانی که میانافزار خود را مقداردهی اولیه میکنید. اینجاست که اشیاء سراسری، منطق پیکربندی و غیره را تنظیم میکنید — همه چیزی که فقط یک بار در طول عمر برنامه نیاز به اتفاق افتادن دارد.
-
بخش دوم در هر درخواست اجرا میشود. مثلاً در یک میانافزار پایگاه داده، شیء سراسری پایگاه داده خود را به context درخواست تزریق میکنید. وقتی در context قرار گرفت، سایر میانافزارها و توابع handler شما میتوانند آن را بازیابی و استفاده کنند.
func funcName(params string) gin.HandlerFunc { // <--- // This is part one // ---> // Example initialization: validate input params if err := check(params); err != nil { panic(err) }
return func(c *gin.Context) { // <--- // This is part two // ---> // Example execution per request: inject into context c.Set("TestVar", params) c.Next() }}فرآیند اجرا
بیایید کد مثال زیر را بررسی کنیم:
func main() { router := gin.Default()
router.Use(globalMiddleware())
router.GET("/rest/n/api/*some", mid1(), mid2(), handler)
router.Run()}
func globalMiddleware() gin.HandlerFunc { fmt.Println("globalMiddleware...1")
return func(c *gin.Context) { fmt.Println("globalMiddleware...2") c.Next() fmt.Println("globalMiddleware...3") }}
func handler(c *gin.Context) { fmt.Println("exec handler.")}
func mid1() gin.HandlerFunc { fmt.Println("mid1...1")
return func(c *gin.Context) {
fmt.Println("mid1...2") c.Next() fmt.Println("mid1...3") }}
func mid2() gin.HandlerFunc { fmt.Println("mid2...1")
return func(c *gin.Context) { fmt.Println("mid2...2") c.Next() fmt.Println("mid2...3") }}بر اساس بخش اجزای تشکیلدهنده بالا، وقتی فرآیند Gin را اجرا میکنید، ابتدا بخش اول هر میانافزار اجرا شده و اطلاعات زیر را چاپ میکند:
globalMiddleware...1mid1...1mid2...1ترتیب مقداردهی اولیه به شکل زیر است:
globalMiddleware...1 | vmid1...1 | vmid2...1وقتی درخواستی ارسال میکنید — مثلاً curl -v localhost:8080/rest/n/api/some — بخش دوم هر میانافزار به ترتیب اجرا شده و خروجی زیر را تولید میکند:
globalMiddleware...2mid1...2mid2...2exec handler.mid2...3mid1...3globalMiddleware...3به عبارت دیگر، ترتیب اجرا به شکل زیر است:
globalMiddleware...2 | vmid1...2 | vmid2...2 | vexec handler. | vmid2...3 | vmid1...3 | vglobalMiddleware...3