document: add docs dir and middleware document (#1521)
* init docs dir * add middleware document * fix indent * update docs
This commit is contained in:
		
							
								
								
									
										137
									
								
								docs/how-to-build-an-effective-middleware.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										137
									
								
								docs/how-to-build-an-effective-middleware.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,137 @@
 | 
				
			|||||||
 | 
					# How to build one effective middleware?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Consitituent part
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The middleware has two parts:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - part one is what is executed once, when you initalize your middleware. That's where you set up all the global objects, logicals etc. Everything that happens one per application lifetime.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  - part two is what executes on every request. For example, a database middleware you simply inject your "global" database object into the context. Once it's inside the context, you can retrieve it from within other middlewares and your handler furnction.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					func funcName(params string) gin.HandlerFunc {
 | 
				
			||||||
 | 
					    // <---
 | 
				
			||||||
 | 
					    // This is part one
 | 
				
			||||||
 | 
					    // --->
 | 
				
			||||||
 | 
					    // The follow code is an example
 | 
				
			||||||
 | 
					    if err := check(params); err != nil {
 | 
				
			||||||
 | 
					        panic(err)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return func(c *gin.Context) {
 | 
				
			||||||
 | 
					        // <---
 | 
				
			||||||
 | 
					        // This is part two
 | 
				
			||||||
 | 
					        // --->
 | 
				
			||||||
 | 
					        // The follow code is an example
 | 
				
			||||||
 | 
					        c.Set("TestVar", params)
 | 
				
			||||||
 | 
					        c.Next()    
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Execution process
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Firstly, we have the follow example code:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					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")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					According to [Consitituent part](#consitituent-part) said, when we run the gin process, **part one** will execute firstly and will print the follow information:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					globalMiddleware...1
 | 
				
			||||||
 | 
					mid1...1
 | 
				
			||||||
 | 
					mid2...1
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					And init order are:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					globalMiddleware...1
 | 
				
			||||||
 | 
					    |
 | 
				
			||||||
 | 
					    v
 | 
				
			||||||
 | 
					mid1...1
 | 
				
			||||||
 | 
					    |
 | 
				
			||||||
 | 
					    v
 | 
				
			||||||
 | 
					mid2...1
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					When we curl one request `curl -v localhost:8080/rest/n/api/some`, **part two** will execute their middleware and output the following information:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					globalMiddleware...2
 | 
				
			||||||
 | 
					mid1...2
 | 
				
			||||||
 | 
					mid2...2
 | 
				
			||||||
 | 
					exec handler.
 | 
				
			||||||
 | 
					mid2...3
 | 
				
			||||||
 | 
					mid1...3
 | 
				
			||||||
 | 
					globalMiddleware...3
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					In other words, run order are:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```go
 | 
				
			||||||
 | 
					globalMiddleware...2
 | 
				
			||||||
 | 
					    |
 | 
				
			||||||
 | 
					    v
 | 
				
			||||||
 | 
					mid1...2
 | 
				
			||||||
 | 
					    |
 | 
				
			||||||
 | 
					    v
 | 
				
			||||||
 | 
					mid2...2
 | 
				
			||||||
 | 
					    |
 | 
				
			||||||
 | 
					    v
 | 
				
			||||||
 | 
					exec handler.
 | 
				
			||||||
 | 
					    |
 | 
				
			||||||
 | 
					    v
 | 
				
			||||||
 | 
					mid2...3
 | 
				
			||||||
 | 
					    |
 | 
				
			||||||
 | 
					    v
 | 
				
			||||||
 | 
					mid1...3
 | 
				
			||||||
 | 
					    |
 | 
				
			||||||
 | 
					    v
 | 
				
			||||||
 | 
					globalMiddleware...3
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
		Reference in New Issue
	
	Block a user