-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
96 changed files
with
1,424 additions
and
2,852 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,6 +35,7 @@ Gin is a web framework written in Go (Golang). It features a martini-like API wi | |
- [Blank Gin without middleware by default](#blank-gin-without-middleware-by-default) | ||
- [Using middleware](#using-middleware) | ||
- [How to write log file](#how-to-write-log-file) | ||
- [Custom Log Format](#custom-log-format) | ||
- [Model binding and validation](#model-binding-and-validation) | ||
- [Custom Validators](#custom-validators) | ||
- [Only Bind Query String](#only-bind-query-string) | ||
|
@@ -111,7 +112,7 @@ $ govendor fetch github.com/gin-gonic/[email protected] | |
4. Copy a starting template inside your project | ||
|
||
```sh | ||
$ curl https://raw.githubusercontent.com/gin-gonic/gin/master/examples/basic/main.go > main.go | ||
$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go | ||
``` | ||
|
||
5. Run your project | ||
|
@@ -211,13 +212,12 @@ $ go build -tags=jsoniter . | |
|
||
## API Examples | ||
|
||
You can find a number of ready-to-run examples at [Gin examples repository](https://github.com/gin-gonic/examples). | ||
|
||
### Using GET, POST, PUT, PATCH, DELETE and OPTIONS | ||
|
||
```go | ||
func main() { | ||
// Disable Console Color | ||
// gin.DisableConsoleColor() | ||
|
||
// Creates a gin router with default middleware: | ||
// logger and recovery (crash-free) middleware | ||
router := gin.Default() | ||
|
@@ -362,7 +362,11 @@ ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou] | |
|
||
#### Single file | ||
|
||
References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](examples/upload-file/single). | ||
References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/single). | ||
|
||
`file.Filename` **SHOULD NOT** be trusted. See [`Content-Disposition` on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) and [#1693](https://github.com/gin-gonic/gin/issues/1693) | ||
|
||
> The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done. | ||
```go | ||
func main() { | ||
|
@@ -393,7 +397,7 @@ curl -X POST http://localhost:8080/upload \ | |
|
||
#### Multiple files | ||
|
||
See the detail [example code](examples/upload-file/multiple). | ||
See the detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple). | ||
|
||
```go | ||
func main() { | ||
|
@@ -529,6 +533,85 @@ func main() { | |
} | ||
``` | ||
|
||
### Custom Log Format | ||
```go | ||
func main() { | ||
router := gin.New() | ||
|
||
// LoggerWithFormatter middleware will write the logs to gin.DefaultWriter | ||
// By default gin.DefaultWriter = os.Stdout | ||
router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string { | ||
|
||
// your custom format | ||
return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n", | ||
param.ClientIP, | ||
param.TimeStamp.Format(time.RFC1123), | ||
param.Method, | ||
param.Path, | ||
param.Request.Proto, | ||
param.StatusCode, | ||
param.Latency, | ||
param.Request.UserAgent(), | ||
param.ErrorMessage, | ||
) | ||
})) | ||
router.Use(gin.Recovery()) | ||
|
||
router.GET("/ping", func(c *gin.Context) { | ||
c.String(200, "pong") | ||
}) | ||
|
||
router.Run(":8080") | ||
} | ||
``` | ||
|
||
**Sample Output** | ||
``` | ||
::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" " | ||
``` | ||
|
||
### Controlling Log output coloring | ||
|
||
By default, logs output on console should be colorized depending on the detected TTY. | ||
|
||
Never colorize logs: | ||
|
||
```go | ||
func main() { | ||
// Disable log's color | ||
gin.DisableConsoleColor() | ||
|
||
// Creates a gin router with default middleware: | ||
// logger and recovery (crash-free) middleware | ||
router := gin.Default() | ||
|
||
router.GET("/ping", func(c *gin.Context) { | ||
c.String(200, "pong") | ||
}) | ||
|
||
router.Run(":8080") | ||
} | ||
``` | ||
|
||
Always colorize logs: | ||
|
||
```go | ||
func main() { | ||
// Force log's color | ||
gin.ForceConsoleColor() | ||
|
||
// Creates a gin router with default middleware: | ||
// logger and recovery (crash-free) middleware | ||
router := gin.Default() | ||
|
||
router.GET("/ping", func(c *gin.Context) { | ||
c.String(200, "pong") | ||
}) | ||
|
||
router.Run(":8080") | ||
} | ||
``` | ||
|
||
### Model binding and validation | ||
|
||
To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz). | ||
|
@@ -579,7 +662,7 @@ func main() { | |
// <?xml version="1.0" encoding="UTF-8"?> | ||
// <root> | ||
// <user>user</user> | ||
// <password>123</user> | ||
// <password>123</password> | ||
// </root>) | ||
router.POST("/loginXML", func(c *gin.Context) { | ||
var xml Login | ||
|
@@ -646,9 +729,8 @@ When running the above example using the above the `curl` command, it returns er | |
|
||
### Custom Validators | ||
|
||
It is also possible to register custom validators. See the [example code](examples/custom-validation/server.go). | ||
It is also possible to register custom validators. See the [example code](https://github.com/gin-gonic/examples/tree/master/custom-validation/server.go). | ||
|
||
[embedmd]:# (examples/custom-validation/server.go go) | ||
```go | ||
package main | ||
|
||
|
@@ -711,7 +793,7 @@ $ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09" | |
``` | ||
|
||
[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way. | ||
See the [struct-lvl-validation example](examples/struct-lvl-validations) to learn more. | ||
See the [struct-lvl-validation example](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) to learn more. | ||
|
||
### Only Bind Query String | ||
|
||
|
@@ -1201,7 +1283,7 @@ You may use custom delims | |
|
||
#### Custom Template Funcs | ||
|
||
See the detail [example code](examples/template). | ||
See the detail [example code](https://github.com/gin-gonic/examples/tree/master/template). | ||
|
||
main.go | ||
|
||
|
@@ -1421,7 +1503,6 @@ func main() { | |
|
||
example for 1-line LetsEncrypt HTTPS servers. | ||
|
||
[embedmd]:# (examples/auto-tls/example1/main.go go) | ||
```go | ||
package main | ||
|
||
|
@@ -1446,7 +1527,6 @@ func main() { | |
|
||
example for custom autocert manager. | ||
|
||
[embedmd]:# (examples/auto-tls/example2/main.go go) | ||
```go | ||
package main | ||
|
||
|
@@ -1480,7 +1560,6 @@ func main() { | |
|
||
See the [question](https://github.com/gin-gonic/gin/issues/346) and try the following example: | ||
|
||
[embedmd]:# (examples/multiple-service/main.go go) | ||
```go | ||
package main | ||
|
||
|
@@ -1578,9 +1657,8 @@ An alternative to endless: | |
* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server. | ||
* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers. | ||
|
||
If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](./examples/graceful-shutdown) example with gin. | ||
If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) example with gin. | ||
|
||
[embedmd]:# (examples/graceful-shutdown/graceful-shutdown/server.go go) | ||
```go | ||
// +build go1.8 | ||
|
||
|
@@ -1592,6 +1670,7 @@ import ( | |
"net/http" | ||
"os" | ||
"os/signal" | ||
"syscall" | ||
"time" | ||
|
||
"github.com/gin-gonic/gin" | ||
|
@@ -1619,7 +1698,10 @@ func main() { | |
// Wait for interrupt signal to gracefully shutdown the server with | ||
// a timeout of 5 seconds. | ||
quit := make(chan os.Signal) | ||
signal.Notify(quit, os.Interrupt) | ||
// kill (no param) default send syscanll.SIGTERM | ||
// kill -2 is syscall.SIGINT | ||
// kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it | ||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) | ||
<-quit | ||
log.Println("Shutdown Server ...") | ||
|
||
|
@@ -1628,6 +1710,11 @@ func main() { | |
if err := srv.Shutdown(ctx); err != nil { | ||
log.Fatal("Server Shutdown:", err) | ||
} | ||
// catching ctx.Done(). timeout of 5 seconds. | ||
select { | ||
case <-ctx.Done(): | ||
log.Println("timeout of 5 seconds.") | ||
} | ||
log.Println("Server exiting") | ||
} | ||
``` | ||
|
@@ -1674,7 +1761,7 @@ func loadTemplate() (*template.Template, error) { | |
} | ||
``` | ||
|
||
See a complete example in the `examples/assets-in-binary` directory. | ||
See a complete example in the `https://github.com/gin-gonic/examples/tree/master/assets-in-binary` directory. | ||
|
||
### Bind form-data request with custom struct | ||
|
||
|
@@ -1750,24 +1837,6 @@ $ curl "http://localhost:8080/getd?field_x=hello&field_d=world" | |
{"d":"world","x":{"FieldX":"hello"}} | ||
``` | ||
|
||
**NOTE**: NOT support the follow style struct: | ||
|
||
```go | ||
type StructX struct { | ||
X struct {} `form:"name_x"` // HERE have form | ||
} | ||
|
||
type StructY struct { | ||
Y StructX `form:"name_y"` // HERE have form | ||
} | ||
|
||
type StructZ struct { | ||
Z *StructZ `form:"name_z"` // HERE have form | ||
} | ||
``` | ||
|
||
In a word, only support nested custom struct which have no `form` now. | ||
|
||
### Try to bind body into different structs | ||
|
||
The normal methods for binding request body consumes `c.Request.Body` and they | ||
|
@@ -1830,7 +1899,6 @@ performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)). | |
|
||
http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information. | ||
|
||
[embedmd]:# (examples/http-pusher/main.go go) | ||
```go | ||
package main | ||
|
||
|
@@ -2017,7 +2085,6 @@ func TestPingRoute(t *testing.T) { | |
|
||
Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework. | ||
|
||
* [drone](https://github.com/drone/drone): Drone is a Continuous Delivery platform built on Docker, written in Go. | ||
* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go. | ||
* [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform. | ||
* [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow. | ||
|
Oops, something went wrong.