Skip to content

Commit

Permalink
document: add docs dir and middleware document (gin-gonic#1521)
Browse files Browse the repository at this point in the history
* init docs dir

* add middleware document

* fix indent

* update docs
  • Loading branch information
thinkerou authored and justinfx committed Nov 3, 2018
1 parent e3a3b89 commit d369746
Showing 1 changed file with 137 additions and 0 deletions.
137 changes: 137 additions & 0 deletions docs/how-to-build-an-effective-middleware.md
Original file line number Diff line number Diff line change
@@ -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
```

0 comments on commit d369746

Please sign in to comment.