Как создать эффективное промежуточное программное обеспечение? (Middleware)
Constituent parts
Промежуточное ПО (Middleware) состоит из двух частей:
-
первая часть - это то, что выполняется один раз, когда вы инициализируете промежуточное ПО. В ней вы устанавливаете все глобальные объекты, логики и т. д. Все это происходит один раз за время жизни приложения.
-
Вторая часть - это то, что выполняется при каждом запросе. Например, в промежуточном ПО для работы с базами данных вы просто вводите свой “глобальный” объект базы данных в контекст. Как только он окажется внутри контекста, вы сможете получить его из других промежуточных модулей и из вашей функции-обработчика.
func funcName(params string) gin.HandlerFunc { // <--- // This is part one // ---> // The following code is an example if err := check(params); err != nil { panic(err) }
return func(c *gin.Context) { // <--- // This is part two // ---> // The following code is an example 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") }}
Согласно Составные части, когда мы запускаем процесс джина, часть первая будет выполняться первой и выведет следующую информацию:
globalMiddleware...1mid1...1mid2...1
And init order is:
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